I have problems with implementing a dropdown (like a spinner) list in my customized ActionBar. I've tried several solutions, including getActionView() but it doesn't work :/
Here is my code; #Override public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.planner_menu, menu);
MenuItem category_item = menu.findItem(R.id.CategoryAppointment);
Spinner spinner =(Spinner) category_item.getActionView();
String[] categories = new String[]{"meeting","training","puls","medicin","bloodsample"};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_dropdown_item,categories);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
parent.setSelection(position);
switch (position) {
case 0:
String category = parent.getSelectedItem().toString();
Toast.makeText(parent.getContext(),
"OnItemSelectedListener : " + category, Toast.LENGTH_SHORT).show();
// Take string and compare it in database.
DB.getAllAppointmentsByCategory(category);
break;
case 1:
// Take string and compare it in database.
break;
case 2:
// Take string and compare it in database.
break;
case 3:
// Take string and compare it in database.
break;
case 4:
// Take string and compare it in database.
break;
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
for (int j = 0; j < menu.size(); j++) {
MenuItem item = menu.getItem(j);
Log.d("TAG", "set flag for " + item.getTitle());
item.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_ALWAYS);
}
return true;}
And here is the the options from the meny.
public boolean onOptionsItemSelected(MenuItem item){
switch (item.getItemId()){
case R.id.AllAppointments:
//DB.getUsersAppointment();
return true;
case R.id.WeekAppointment:
//DB.getUsersAppointmentByWeek(date);
return true;
case R.id.CategoryAppointment:
// setupSpinner();
//DB.getUsersAppointmentByCategory(category);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
The code from the XML file.
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" tools:context=".Planning">
<item android:id="#+id/AllAppointments" android:title="All"
android:orderInCategory="10"
app:showAsAction="always|withText">
</item>
<item android:id="#+id/WeekAppointment"
android:title="Week"
android:orderInCategory="10"
app:showAsAction="always|withText"
>
</item>
<item android:id="#+id/CategoryAppointment"
android:title="Cathegories"
android:orderInCategory="10"
app:showAsAction="always|withText"
>
</item>
`
In item id -> CategoryAppointment I want to show a dropdown meny where the user can choose between diffent categories and then list out the data from the database.
I've been working with this for the past hours but I can't seem to fix it. Can someone please explain to me what I have to do and what it is that i'm doing wrong here.
Thank you.
Related
I have a ListView where I show a menu on the long click. In onContextItemSelected I have a logic to handle the action. I need to know what item in ListView is selected.
If a user selects item that isn't a submenu, I can use MenuItem.getMenuInfo().
But if a user selects a submenu, MenuItem.getMenuInfo() returns null.
What is the correct way how to determine the selected item if there's a submenu ?
The menu:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/Edit" android:title="Edit" />
<item android:id="#+id/Settings" android:title="Settings">
<menu>
<item android:id="#+id/V1" android:title="V1" />
...
</menu>
</item>
</menu>
onContextItemSelected:
#Override
public boolean onContextItemSelected(MenuItem Item) {
AdapterView.AdapterContextMenuInfo AdapterInfo = (AdapterView.AdapterContextMenuInfo)Item.getMenuInfo(); // getMenuInfo returns null if V1 is selected (submenu) but works if selected item isn't submenu, e.g., 'Edit' as per above XML
UserItem SelectedItem = MyAdapter.getItem(AdapterInfo.position); // MyAdapter is the instance of class that inherits from ArrayAdapter<UserItem> i.e. adapter for ListView
}
you need to do 3 things
1.provide a default section in your switch statement that handles your menu items
2.save off the info.position to a member variable in your Activity
3.when you detect that info is null, use the var you created in step 2
private int mParentContextMenuListIndex;
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info;
try {
info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
} catch (ClassCastException e) {
Log.e(TAG, "bad menuInfo", e);
return false;
}
//if info == null, it means we have a submenu to deal with, use the saved info.position
int idxOfList = (info!=null) ? info.position : this.mParentContextMenuListIndex;
...
switch (item.getItemId()) {
case R.id.context_menu_item_1:
... //use idxOfList instead of info.position
return true;
case R.id.context_menu_item_2:
... //use idxOfList instead of info.position
return true;
case R.id.context_menu_item_3:
... //use idxOfList instead of info.position
return true;
case R.id.context_submenu_item_1:
... //use idxOfList instead of info.position
return true;
case R.id.context_submenu_item_2:
... //use idxOfList instead of info.position
return true;
default: //can handle submenus if we save off info.position
this.mParentContextMenuListIndex = idxOfList;
}//switch
return super.onContextItemSelected(item);
}
Why don't you use onItemClickLitener() for all the items in you listview without dividing them on munu items and submenu items?
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
String s = listView.getItemAtPosition(i).toString();
}
});
So i will be your item position.
If you still want to work with submenu items you need to implement onOptionsItemSelected(MenuItem item) method and catch onclick events based on the id of submenu items .
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case 10:
//do smth here
return true;
case 15:
//do smth here
return true;
case 20:
//do smth here
return true;
default:
return super.onOptionsItemSelected(item);
}
}
I want custom ListView layout which has multiple selection , so I am doing custom adapter but how I can allow user to select multiple . In default ListView we are given choice mode but I want layout different not checkbook
<Imageview>
<Textview>
Do I have to manage in onItemClick or any method is der ? Small snippet will help
For this you need ListView.CHOICE_MODE_MULTIPLE_MODAL. See the following code snippet,
First create a ListView and it's adapter,
listView = (ListView) findViewById(R.id.listView);
adapter = new AttendanceListAdapter(this, attendanceList);
Set the List choice mode to multiple and add a Multi choice listener,
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listView.setMultiChoiceModeListener(new ModeCallback());
listView.setAdapter(adapter);
Your Multi choice listener should look something like this,
private class ModeCallback implements ListView.MultiChoiceModeListener {
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.list_select_menu, menu);
mode.setTitle("Select Items");
return true;
}
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return true;
}
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.share:
Toast.makeText(AddAttendanceActivity.this, "Shared " + listView.getCheckedItemCount() +
" items", Toast.LENGTH_SHORT).show();
mode.finish();
break;
default:
Toast.makeText(AddAttendanceActivity.this, "Clicked " + item.getTitle(),
Toast.LENGTH_SHORT).show();
break;
}
return true;
}
public void onDestroyActionMode(ActionMode mode) {
}
public void onItemCheckedStateChanged(ActionMode mode,
int position, long id, boolean checked) {
final int checkedCount = listView.getCheckedItemCount();
switch (checkedCount) {
case 0:
mode.setSubtitle(null);
break;
case 1:
mode.setSubtitle("One item selected");
break;
default:
mode.setSubtitle("" + checkedCount + " items selected");
break;
}
}
}
Now if you want the selected rows to highlighted add this style to the root element of your list items layout.
<style name="activated" parent="AppTheme">
<item name="android:background">?android:attr/activatedBackgroundIndicator</item>
</style>
I think you you want something like whatsup select for that on long click listener you can change color of custom listview items(rows)
I have options menu in my toolbar with radibutton item :
<item
android:id="#+id/map_menu"
android:icon="#drawable/ic_layer"
android:orderInCategory="102"
app:showAsAction="always"
android:title="#string/action_settings">
<menu>
<group
android:id="#+id/map_types_group"
android:checkableBehavior="single" >
<item
android:id="#+id/map_terrain"
android:orderInCategory="1"
app:showAsAction="ifRoom"
android:title="#string/map_terrain"/>
<item
android:id="#+id/map_normal"
android:orderInCategory="2"
android:checked="true"
app:showAsAction="ifRoom"
android:title="#string/map_normal"/>
<item
android:id="#+id/map_hybrid"
android:orderInCategory="3"
app:showAsAction="ifRoom"
android:title="#string/map_hybrid"/>
</group>
</menu>
</item>
I want to restore selected radiobutton when orientation change happened in onSaveInstanceState,onRestoreInstanceState but i can't understand how to get selected button from radiogroup in options menu.
Here is a fully working and tested example. With this code in place, no matter how many times you rotate the screen, the currently selected item will persist.
First, create these instance variables to keep track of the state of the menu and have a name for the preference you will be saving in the Bundle:
private final static String MENU_SELECTED = "selected";
private int selected = -1;
MenuItem menuItem;
The saveInstanceState() method should save off the currently selected value:
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putInt(MENU_SELECTED, selected);
super.onSaveInstanceState(savedInstanceState);
}
Update the currently selected item in onOptionsItemSelected():
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
Log.d("settings", "id: " + id);
return true;
}
if (id == R.id.map_terrain){
Log.d("menuitem", "terrain id: " + id);
selected = id;
item.setChecked(true);
return true;
}
if (id == R.id.map_normal){
Log.d("menuitem", "normal id: " + id);
selected = id;
item.setChecked(true);
return true;
}
if (id == R.id.map_hybrid){
Log.d("menuitem", "hybrid id: " + id);
selected = id;
item.setChecked(true);
return true;
}
return super.onOptionsItemSelected(item);
}
In onCreate(), load the saved data if it exists:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState != null){
selected = savedInstanceState.getInt(MENU_SELECTED);
}
}
And then re-select the previously selected item in onCreateOptionsMenu():
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
if (selected == -1){
return true;
}
switch (selected){
case R.id.map_terrain:
menuItem = (MenuItem) menu.findItem(R.id.map_terrain);
menuItem.setChecked(true);
break;
case R.id.map_normal:
menuItem = (MenuItem) menu.findItem(R.id.map_normal);
menuItem.setChecked(true);
break;
case R.id.map_hybrid:
menuItem = (MenuItem) menu.findItem(R.id.map_hybrid);
menuItem.setChecked(true);
break;
}
return true;
}
MenuItem in onOptionsItemSelected has item.isChecked() method, just use it. You can store one boolean field(it wouldn't be a bad thing in my opinion) and change it whenever change in radiog group occurs
Then you can have your id by simply calling:
if(item.isChecked()) {
your_id_field = item.getItemId()
}
Create a variable eg: menu_selection to store the id of the menu item selected. Initially you can define 0
private int menu_selection = 0;
Save and restore the value of the variable using onSaveInstanceState and onRestoreInstanceState
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save the id of radio button selected in the menu
savedInstanceState.putInt("selection", menu_selection);
super.onSaveInstanceState(savedInstanceState);
}
#Override
public void onRestoreInstanceState(#NonNull Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// Restore state members from saved instance
menu_selection = savedInstanceState.getInt("selection");
}
In onOptionsItemSelected , assign the id of the menu item selected item.getItemId() to the variable
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
if (item.isChecked()) {
item.setChecked(false);
} else {
item.setChecked(true);
menu_selection = item.getItemId();
}
switch (item.getItemId()) {
case R.id.map_terrain:
//some action here
return true;
case R.id.map_normal:
//some action here
return true;
case R.id.map_hybrid:
//some action here
return true;
default:
return super.onOptionsItemSelected(item);
}
}
In onCreateOptionsMenu , find the menu item identified with the value in the variable and check it
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_main, menu);
if (menu_selection != 0) {
MenuItem selected = (MenuItem) menu.findItem(menu_selection);
selected.setChecked(true);
}
return true;
}
Ok I'm sure this is a dumb question but I couldn't find the answer online. I want to register one of the menu Items for a context Menu, but I don't know how to can't figure out how to access the MenuItem as a view. So when I click one of the buttons on the ActionBar of my application, I want a context menu to pop up. I'm guessing this has to be done in OnCreateOptionsMenu?
Edit: Update... Adding this code works partially but overrides my Drawable.
XML
<item android:id="#+id/Favorites"
android:title="favorite_label"
android:icon="#android:drawable/ic_menu_myplaces"
android:actionViewClass="android.widget.ImageButton"
android:showAsAction="always"
/>
Main Activity
FavoriteButton = (ImageButton) menu.findItem(R.id.Favorites).getActionView();
FavoriteButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
registerForContextMenu(v);
}
});
Hi follow below link exmple link
ListView list = (ListView)findViewById(R.id.list);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.listitem, Countries);
list.setAdapter(adapter);
registerForContextMenu(list);
change registerForContextMenu(list); to registerForContextMenu(buttonname);
i hope it useful to you.
In the resource/menu/main.xml add the below code:
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<menu>
<item
android:id="#+id/gray"
android:title="#string/gray" />
<item
android:id="#+id/green"
android:title="#string/green" />
<item
android:id="#+id/red"
android:title="#string/red" />
<item
android:id="#+id/orange"
android:title="#string/orange" />
<item
android:id="#+id/purple"
android:title="#string/dark_blue" />
</menu>
</item>
</menu>
and in the main activity you can access this by overridding the belo method:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.gray:
color = Color.parseColor("#FF666666");
return true;
case R.id.green:
color = Color.parseColor("#FF96AA39");
return true;
case R.id.orange:
color = Color.parseColor("#FFF4842D");
return true;
case R.id.purple:
color = Color.parseColor("#FF5161BC");
return true;
}
return super.onOptionsItemSelected(item);
}
Here is what I have made:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// "menu_main" is the menubar of my actionbar menu
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
// "item" is the menu button I have pressed
int id = item.getItemId();
// "Settings" button
if (id == R.id.action_settings) {
return true;
}
// Difficulty button to change the difficulty of my game
else if (id == R.id.action_difficulty) {
View view = findViewById(R.id.action_difficulty);
registerForContextMenu(view);
openContextMenu(view);
}
return super.onOptionsItemSelected(item);
}
This works fine for me!
BUT! If your menubar button is behind the "three dots" button, the line
registerForContextMenu(view);
will crash your application. I'm figuring out why..
Trying to activate CAB menu when clicking on MenuItem from ActionBar. Here is how I set the GridView for listening to Multi Choice. The multiModeChoiceListener is working fine when I long press on Any item in the GridView. It is working fine. Now I have a requirement to activate the CAB menu when do press on a menu item in Action Bar. Once it is pressed, the CAB menu should read that 0 items are selected. After that it should allow me to select items from GridView on single clicks. How can I achieve this feature?
GridView set listener:
gv.setChoiceMode(GridView.CHOICE_MODE_MULTIPLE_MODAL);
gv.setMultiChoiceModeListener(new MultiChoiceModeListener());
MultiChoiceModeListener.java
public class MultiChoiceModeListener implements
GridView.MultiChoiceModeListener {
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.featured_multiselect, menu);
MenuItem mi = menu.findItem(R.id.close);
mi.setIcon(R.drawable.cancel);
mode.setTitle("Select Items");
return true;
}
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return true;
}
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
Toast.makeText(getApplicationContext(), item.getTitle(),
Toast.LENGTH_SHORT).show();
if (item.getTitle().toString().equalsIgnoreCase("Close")) {
mode.finish();
}
return true;
}
public void onDestroyActionMode(ActionMode mode) {
new ChangeNotifier().changeOnFavoriteStore = true;
new AddFavorites().execute("add", device_id, dataArray);
if (notify == true) {
Toast.makeText(getApplicationContext(),
"Selected items are added to Favorites",
Toast.LENGTH_SHORT).show();
notify = false;
}
}
public void onItemCheckedStateChanged(ActionMode mode, int position,
long id, boolean checked) {
int selectCount = gridView.getCheckedItemCount();
if (selectCount > 0) {
notify = true;
dataArray.add(position);
switch (selectCount) {
case 1:
mode.setSubtitle("One item added to favorites");
break;
default:
mode.setSubtitle("" + selectCount
+ " items added to favorites");
break;
}
}
}
OnMenuItemClick method:
public boolean onPrepareOptionsMenu(final Menu menu) {
final MenuItem editItem = menu.findItem(R.id.editit);
editItem.setOnMenuItemClickListener(new OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
//the CAB menu should be activated here. So that it reads that 0 items are selected in ActionBar
return false;
}
});
From your question I understand that you're trying to start the GridView associated CAB from clicking one of the menu items. I don't know if you can do this(but I may be mistaken) as the MultiChoiceModeListener expects an item to be checked to start. Depending on your layout and the overall appearance of the GridView, I think you could have a dummy item(as an extra item in the adapter) at the end of the GridView(with no content showing) and use setItemChecked(dummyItemPosition, true) to start the GridView CAB. Of course you'll need to have additional logic to take care of that extra item in your MultiChoiceModeListener:
public void onItemCheckedStateChanged(ActionMode mode, int position,
long id, boolean checked) {
if (position == theDummyPosition)
return; // so we start the CAB but there aren't any items checked
}
int selectCount = gridView.getCheckedItemCount();
if (selectCount > 0) {
notify = true;
dataArray.add(position);
// if you select another item you'll have two selected items(because of the dummy item) so you need to take care of it
switch (selectCount) {
case 1:
mode.setSubtitle("One item added to favorites");
break;
default:
mode.setSubtitle("" + selectCount
+ " items added to favorites");
break;
}
}
}
The solution above is a hack, most likely it would be much easier to lose the MultiChoiceModeListener and simply start an ActionMode that you can manipulate for both situations.