I have a ListView in my activity. I also have a menu and there is a menuitem for saving the list. I want to make it behave like the pseudocode below:
if (myList.size() > 0) {
menuitem.setVisible(true);
} else {
menuitem.setVisible(false);
}
I want the "save" menuitem to show only when there is at least one item in the listview. I have a custom ArrayAdapter implementation also, can this action be made from there? Or is there any kind of listener I could use?
Any help is appreciated!
EDIT:
JDev answer is the solution.
I changed only one thing: I moved the list size checking to notifyDataSetChanged() method inside my custom ArrayAdapter and now it works!
/**
* {#inheritDoc}
*/
#Override
public void notifyDataSetChanged() {
// Hide/show 'save' menuitem
if (mListItems.size() > 0) {
mListener.setMenuItemVisible(true);
} else {
mListener.setMenuItemVisible(false);
}
super.notifyDataSetChanged();
}
After getting the ListView length. Add invalidateOptionsMenu(); to call onCreateOptionsMenu().
Check if ListView is empty or not here,
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
...
MenuItem menuitem = menu.findItem(R.id.addAction);
if (myList.size() > 0) {
menuitem.setVisible(true);
} else {
menuitem.setVisible(false);
}
}
Comment below if you have any query.
In your custom array adapter, you can do something like this:
CustomArrayAdapter.java
public interface MenuListener {
void setMenuItemVisible(boolean state);
}
private MenuListener mListener;
private Item[] mListItems; // The list of items that your adapter handles
public void setMenuListener(MenuListener listener) {
mListener = listener;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ListView listview = convertView.findViewById(R.id.yourListViewId);
if (mListItems.size() > 0) {
mListener.setMenuItemVisible(true);
} else {
mListener.setMenuItemVisible(false);
}
}
Activity.java:
public class Activity implements CustomArrayAdapter.MenuListener {
private MenuItem menuItem; // The menu item that you wanna show/hide
....
#Override
public void onCreate(Bundle savedInstanceState) {
CustomArrayAdapter adapter = new CustomArrayAdapter(params...);
adapter.setMenuListener(this);
// Set listView adapter
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
menuItem = menu.findItem(R.id.menuItemId); // Save the menu item that you want to show/hide later
...
}
#Override
public void setMenuItemVisible(boolean state) {
menuItem.setVisible(state);
}
}
You shouldn't have to implement listeners or other convoluted methods for something as simple as this. In your Activity, simply add one line (after you've fetched your array to be passed on to your adapter):
menuitem.setVisible(array!= null && array.length() > 0 ? true: false);
// array.length() / array.length / array.size() -- whichever is suitable
EDIT: if you're allowing users to add/remove from the list, then disregard the one-liner above. You could simply include your Activity as a parameter to your adapter's constructor. In your activity, add a public method such as:
public void showHideMenuItem(int size) {
menuitem.setVisible(size > 0 ? true: false);
}
In your adapter, call the above method from wherever you're allowing adding/removing of items:
activity.showHideMenuItem(items.getCount());
To set the menuitem's visibility initially, call:
showHideMenuItem(0); // from your Activity's onCreate(), or
activity.showHideMenuItem(0); // from your adapter's constructor
If you've solved this via listener etc and you're happy with it, that's ok, I just personally wouldn't complicate stuff if it isn't necessary. I'd also prefer to determine the menuitem's visibility via the size of the array held by the adapter vs. the number of items in the listview.
can anybody tell me how to change the visibility of a menuitem from another activity?
I have two activities "activity A and B". in one activity A when I press a menu item it saves some strings to the list of activity B and In activity A menuitem visibility set to false. now I want that when I delete that item from activity B which I saved from activity A, with this delete the menuitem visibility in activity A changes to true and it become visible again? so how can I do this. I using database to populate listview.
Activity A
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.atherosclerosis, menu);
return true;
}
// for starting activity from the option or menu//
#Override
public boolean onOptionsItemSelected(MenuItem item) {
SharedPreferences myPrefs = PreferenceManager.getDefaultSharedPreferences(this);
final SharedPreferences.Editor editor = myPrefs.edit();
favClicked = myPrefs.getBoolean("menu_item", false);
switch (item.getItemId()) {
case R.id.id_favorit:
// Add it to the DB and re-draw the ListView
myDb.insertRow("Atherosclerosis", 0, "");
Toast.makeText(getApplicationContext(), "Item Added to favorite list!", Toast.LENGTH_SHORT).show();
favClicked=true;
editor.putBoolean("menu_item", favClicked);
editor.commit();
invalidateOptionsMenu();
return true;
case R.id.id_favorit2:
myDb.deleteRow("Atherosclerosis");
Toast.makeText(getApplicationContext(), "Item deleted from favorite list!", Toast.LENGTH_SHORT).show();
favClicked=false;
editor.putBoolean("menu_item", favClicked);
editor.commit();
invalidateOptionsMenu();
return super.onOptionsItemSelected(item);
}
return true;
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
if(favClicked==true){
menu.findItem(R.id.id_favorit).setVisible(false);
menu.findItem(R.id.id_favorit2).setVisible(true);
}else{
menu.findItem(R.id.id_favorit).setVisible(true);
menu.findItem(R.id.id_favorit2).setVisible(false);
}
Activity B
private void populateListViewFromDB() {
Cursor cursor = myDb.getAllRows();
// Allow activity to manage lifetime of the cursor.
// DEPRECATED! Runs on the UI thread, OK for small/short queries.
startManagingCursor(cursor);
// Setup mapping from cursor to view fields:
String[] fromFieldNames = new String[]
{DBAdapter.KEY_NAME, DBAdapter.KEY_STUDENTNUM};
int[] toViewIDs = new int[]
{R.id.item_name};
// Create adapter to may columns of the DB onto elemesnt in the UI.
SimpleCursorAdapter myCursorAdapter =
new SimpleCursorAdapter(
this, // Context
R.layout.item_layout, // Row layout template
cursor, // cursor (set of DB records to map)
fromFieldNames, // DB Column names
toViewIDs // View IDs to put information in
);
// Set the adapter for the list view
ListView myList = (ListView) findViewById(R.id.favlistView1);
myList.setAdapter(myCursorAdapter);
}
private void registerListClickCallback() {
ListView myList = (ListView) findViewById(R.id.favlistView1);
//This code is for to delete the single item from the listview of favorite list
myList.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
int arg2, final long arg3) {
Cursor cursor = myDb.getRow(arg3);
if (cursor.moveToFirst()) {
new AlertDialog.Builder(FavoriteDiseases.this)
.setTitle("Delete Item")
.setMessage("Do you want to delete this disease?")
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// continue with delete
myDb.deleteItem(arg3);
populateListViewFromDB();
}
})
.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// do nothing
}
})
.show();
}
return true;
}
});
Need a little more context for a good answer how are the activities related is one calling the other?
But in general if activity a is calling activity b. Then you could just call startActivityForResult when starting activity b. When b is finished return a status that informs activity a that the item has been deleted.
To update the menu assuming you are creating your menu by overriding onCreateOptionsMenu, then just have that method check a flag to set a state of the menu item. Then in your onActivityResult method set the flag based on the result of activity b and call invalidateOptionsMenu() which will redraw your options menu.
Hello im trying to use onclicklistener along with onmenuselectlistener in my mainactivity class and the program runs but selecting the popup menu opions dont work they wont set the text to want it want anyone have any idea's? I know i did not implement onMenuSelectListener and maybe thats my problem if it is is there any other way to makes this work?
Here is my code:
public class MainActivity extends Activity implements OnClickListener {
// init variables
Handler uiHandler;
EditText cl;
TextView info;
Button enter;
Button line;
Button arc;
DrawingUtils callDU = new DrawingUtils();
DrawingTools callDT = new DrawingTools();
EditTools callET = new EditTools();
Conversion callConversion = new Conversion();
GLSurfaceView mGLSurface;
String Tag = "Debug";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mGLSurface = new GLSurfaceView(this);
mGLSurface.setRenderer(new BasicRenderer());
setContentView(R.layout.canvas);
FrameLayout v = (FrameLayout) findViewById(R.id.canvas);
v.addView(mGLSurface);
// init views and buttons
info = (TextView) findViewById(R.id.info);
enter = (Button) findViewById(R.id.enter);
line = (Button) findViewById(R.id.line);
arc = (Button) findViewById(R.id.arc);
cl = (EditText) findViewById(R.id.cl);
/*
* Handler for Main Thread uiHandler = new Handler() { public void
* handleMessage(Message msg) { switch (msg.what) {
*
* } Bundle bundle = msg.getData(); String string1 =
* bundle.getString("P1Key"); String string2 =
* bundle.getString("P2Key"); info.setText(string1);
* info.setText(string2); } };
*/
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.enter:
break;
case R.id.line:
break;
case R.id.arc:
break;
}
};
public void CreatePopupMenu(View v) {
PopupMenu mypopupmenu = new PopupMenu(this, v);
MenuInflater inflater = mypopupmenu.getMenuInflater();
inflater.inflate(R.menu.filemenu, mypopupmenu.getMenu());
mypopupmenu.show();
}
#Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
// TODO Auto-generated method stub
switch (item.getItemId()) {
case R.id.newCanas:
info.setText("New");
Log.d(Tag, "New was clicked");
break;
case R.id.open:
break;
case R.id.save:
break;
}
return super.onMenuItemSelected(featureId, item);
}
}
It doesn't look like you're attaching onClickListeners to anything. What that means is you're saying "whenever the onClick event is fired with me as the target, perform this action". But then you're never making yourself a target. Try adding the following code to your onCreate.
arc.setOnClickListener(this);
line.setOnClickListener(this);
enter.setOnClickListener(this);
The same thing happens with the PopupMenu it appears. Try adding mypopupmenu.addOnMenuItemSelectListener(this) right after you inflate the layout for your menu.
Jonathan is right. You should add .setOnClickListener(this); to each of the buttons added after you create them.
For the menu items though, you have to do the following:
1) Create a layout with the items on your menu and store it in your res/menu/ directory.
Example:
main.xml
<item
android:id="#+id/action_settings"
android:orderInCategory="100"
android:showAsAction="never"
android:title="#string/action_settings"/>
</menu>
2) Override the method called: onCreateOptionsMenu() to populate the items in the menu.
Example:
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
3) Override the method onOptionsItemSelected() to do whatever you want with a switch like you were doing with the actionListeners.
4) Additionally, you could also override the method onPrepareOptionsMenu() which is the same as the previous one, but it is called every time the menu opens.
Good luck
I'm trying to change the title of a menu item from outside of the onOptionsItemSelected(MenuItem item) method.
I already do the following;
public boolean onOptionsItemSelected(MenuItem item) {
try {
switch(item.getItemId()) {
case R.id.bedSwitch:
if(item.getTitle().equals("Set to 'In bed'")) {
item.setTitle("Set to 'Out of bed'");
inBed = false;
} else {
item.setTitle("Set to 'In bed'");
inBed = true;
}
break;
}
} catch(Exception e) {
Log.i("Sleep Recorder", e.toString());
}
return true;
}
however I'd like to be able to modify the title of a particular menu item outside of this method.
I would suggest keeping a reference within the activity to the Menu object you receive in onCreateOptionsMenu and then using that to retrieve the MenuItem that requires the change as and when you need it. For example, you could do something along the lines of the following:
public class YourActivity extends Activity {
private Menu menu;
private String inBedMenuTitle = "Set to 'In bed'";
private String outOfBedMenuTitle = "Set to 'Out of bed'";
private boolean inBed = false;
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
// Create your menu...
this.menu = menu;
return true;
}
private void updateMenuTitles() {
MenuItem bedMenuItem = menu.findItem(R.id.bedSwitch);
if (inBed) {
bedMenuItem.setTitle(outOfBedMenuTitle);
} else {
bedMenuItem.setTitle(inBedMenuTitle);
}
}
}
Alternatively, you can override onPrepareOptionsMenu to update the menu items each time the menu is displayed.
As JxDarkAngel suggested, calling this from anywhere in your Activity,
invalidateOptionsMenu();
and then overriding:
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem item = menu.findItem(R.id.bedSwitch);
if (item.getTitle().equals("Set to 'In bed'")) {
item.setTitle("Set to 'Out of bed'");
inBed = false;
} else {
item.setTitle("Set to 'In bed'");
inBed = true;
}
return super.onPrepareOptionsMenu(menu);
}
is a much better choice. I used the answer from https://stackoverflow.com/a/17496503/568197
you can do this create a global "Menu" object then assign it in onCreateOptionMenu
public class ExampleActivity extends AppCompatActivity
Menu menu;
then assign here
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
this.menu = menu;
return true;
}
Then later use assigned Menu object to get required items
menu.findItem(R.id.bedSwitch).setTitle("Your Text");
Create a setOptionsTitle() method and set a field in your class. Such as:
String bedStatus = "Set to 'Out of Bed'";
...
public void setOptionsTitle(String status)
{
bedStatus = status;
}
Now when the menu gets populated, change the title to whatever your status is:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(bedStatus);
// Return true so that the menu gets displayed.
return true;
}
You better use the override onPrepareOptionsMenu
menu.Clear ();
if (TabActual == TabSelec.Anuncio)
{
menu.Add(10, 11, 0, "Crear anuncio");
menu.Add(10, 12, 1, "Modificar anuncio");
menu.Add(10, 13, 2, "Eliminar anuncio");
menu.Add(10, 14, 3, "Actualizar");
}
if (TabActual == TabSelec.Fotos)
{
menu.Add(20, 21, 0, "Subir foto");
menu.Add(20, 22, 1, "Actualizar");
}
if (TabActual == TabSelec.Comentarios)
{
menu.Add(30, 31, 0, "Actualizar");
}
Here an example
I use this code to costum my bottom navigation item
BottomNavigationView navigation = this.findViewById(R.id.my_bottom_navigation);
Menu menu = navigation.getMenu();
menu.findItem(R.id.nav_wall_see).setTitle("Hello");
Declare your menu field.
private Menu menu;
Following is onCreateOptionsMenu() method
public boolean onCreateOptionsMenu(Menu menu) {
this.menu = menu;
try {
getMenuInflater().inflate(R.menu.menu_main,menu);
} catch (Exception e) {
e.printStackTrace();
Log.i(TAG, "onCreateOptionsMenu: error: "+e.getMessage());
}
return super.onCreateOptionsMenu(menu);
}
Following will be your name setter activity. Either through a button click or through conditional code
public void setMenuName(){
menu.findItem(R.id.menuItemId).setTitle(/*Set your desired menu title here*/);
}
This worked for me.
You can do it like this, and no need to dedicate variable:
Toolbar toolbar = findViewById(R.id.toolbar);
Menu menu = toolbar.getMenu();
MenuItem menuItem = menu.findItem(R.id.some_action);
menuItem.setTitle("New title");
Or a little simplified:
MenuItem menuItem = ((Toolbar)findViewById(R.id.toolbar)).getMenu().findItem(R.id.some_action);
menuItem.setTitle("New title");
It works only - after the menu created.
You can Change Menu Item text using below Code: -
fun showPopup(v: View) {
popup = PopupMenu(context, v)
val inflater = popup?.menuInflater
popup?.setOnMenuItemClickListener(this)
inflater?.inflate(R.menu.menu_main, popup?.menu)
val menu: Menu = popup!!.menu
val item = menu.findItem(R.id.name)
if (item.title.equals("Name")) {
item.title = "Safal Bhatia"
}
}
It seems to me that you want to change the contents of menu inside a local method, and this method is called at any time, whenever an event is occurred, or in the activity UI thread.
Why don't you take the instance of Menu in the global variable in onPrepareOptionsMenu when this is overridden and use in this method of yours. Be sure that this method is called whenever an event is occurred (like button click), or in the activity UI thread, handler or async-task post-execute.
You should know in advance the index of this menu item you want to change. After clearing the menu, you need to inflate the menu XML and update your item's name or icon.
For people that need the title set statically.
This can be done in the AndroidManifest.xml
<activity
android:name=".ActivityName"
android:label="Title Text" >
</activity>
I needed to change the menu icon for the fragment. I altered Charles’s answer to this question a bit for the fragment:
private Menu top_menu;
//...
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
setHasOptionsMenu(true);
//...
rootview = inflater.inflate(R.layout.first_content,null);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.fragment_menu, menu);
this.top_menu = menu;
}
// my procedure
private void updateIconMenu() {
if(top_menu!= null) {
MenuItem nav_undo = top_menu.findItem(R.id.action_undo);
nav_undo.setIcon( R.drawable.back);
}
}
I hit this problem too. In my case I wanted to set the string to
reflect additional information using getString.
As stated above you need to find the correct menuItem in the menu and set it in the onPrepareOptionsMenu method. The solutions above didn't handle the case where the item was in a sub menu and for this you need to search the submenu for the item. I wrote a little Kotlin recursive function to allow me to this for multiple items. Code below...
override fun onPrepareOptionsMenu(menu: Menu) {
...
menu.menuSetText(R.id.add_new_card,
getString(R.string.add_card, currentDeck.deckName))
...
}
private fun Menu.getMenuItem(idx: Int, itemId: Int): MenuItem? {
Log.d(TAG, "getMenuItem: $idx of ${this.size()}")
if (idx >= size()) return null
val item = getItem(idx)
if (item.hasSubMenu()) {
val mi = item.subMenu.getMenuItem(0, itemId)
// mi non-null means we found item.
if (mi != null)
return mi
}
if (item != null && item.itemId == itemId)
return item
return getMenuItem(idx + 1, itemId)
}
fun Menu.menuSetText(itemId: Int, title: String) {
val menuItem = getMenuItem(0, itemId)
if (menuItem != null)
menuItem.title = title
else
Log.e(TAG,
"menuSetText to \"$title\": Failed to find ${
"itemId:0x%08x".format(itemId)}"
)
}
I've searched long and far and found a few different ways people are dealing with removing a single and often specific tab from a TabHost object. I would like to try, if I may, to gather all those methods to this single question so that people my "shop" for the right method they need and hopefully get the answer they need to write their code; I also feel that it will cut down on the number of these questions.
At the moment I'm having trouble finding a solution to my code as well. I'm attempting to get rid of a particular tab without touching the others; hopefully I too will find my answer.
I wont pick a particular answer for this question for a while, so please just list the method you used to deal with this problem here for others to see.
Thank you.
Update:
Okay, here is my current code:
TabHost mTabHost;
TabHost.TabSpec spec;
Intent mSettingsIntent;
Intent mSearchIntent;
int tabNum = 1;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mSearchIntent = new Intent().setClass(this, SearchTab.class);
mTabHost = getTabHost();
mTabHost.getTabWidget().setDividerDrawable(R.drawable.tab_divider);
makeTab("Tab");
final Button newSearchBtn = (Button) findViewById(R.id.new_search_btn);
newSearchBtn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// Perform action on clicks
EditText searchBar = (EditText) findViewById(R.id.search_bar);
final String searchString = searchBar.getText().toString();
makeTab(searchString);
}
});
final EditText edittext = (EditText) findViewById(R.id.search_bar);
edittext.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
// If the event is a key-down event on the "enter" button
if ((event.getAction() == KeyEvent.ACTION_DOWN) &&
(keyCode == KeyEvent.KEYCODE_ENTER)) {
// Perform action on key press
EditText searchBar = (EditText) findViewById(R.id.search_bar);
final String searchString = searchBar.getText().toString();
makeTab(searchString);
return true;
}
return false;
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.tab_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.menu_close:
// TODO: Find/define method to close a single tab
closeTab();
return true;
case R.id.menu_settings:
// TODO: Create a basic Settings Activity and call constructor here
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public void makeTab(String tabText) {
String tabTag = "Tab" + tabNum++;
View tabview = createTabView(mTabHost.getContext(), tabText);
spec = mTabHost.newTabSpec(tabTag).setIndicator(tabview).setContent(new Intent().setClass(this, SearchTab.class));
mTabHost.addTab(spec);
mTabHost.setCurrentTabByTag(tabTag);
}
private void closeTab() {
// TODO: Define method for closing a single tab with tabTag
mTabHost.removeViewAt(mTabHost.getCurrentTab());
}
private static View createTabView(final Context context, final String text) {
View view = LayoutInflater.from(context).inflate(R.layout.tabs_bg, null);
TextView tv = (TextView) view.findViewById(R.id.tabsText);
tv.setText(text);
return view;
}
}
My app locks up due to a NullPointer Exception I'm not sure why; I'm still trying to figure out how to read the debugger perspective in Eclispe for clues. I'll update when I have more.