I have a Xamarin Android project that contains a menu bar. I'm almost certain this was working correctly yesterday, but since then, every time I click on a menu bar item such as 'settings', which takes me to the Settings Activity, then go back to the Main activity, the menu bar items are repeating themselves.
So where i just had 'Settings' and 'help', i not have 2 settings, and 2 help items. If i do it again, i will have 3 of each.
I'm assuming this is something to do with the onPause() and onResume() methods as the app goes to another activity. But i can't see where i'm going wrong (i'm new to Android)
My code for generating the menu bar in the Main Activity is:
public override bool OnPrepareOptionsMenu(IMenu menu1)
{
MenuInflater.Inflate(Resource.Menu.myMenuBar, menu1);
return base.OnPrepareOptionsMenu(menu1);
}
public override bool OnOptionsItemSelected(IMenuItem item) //do something when an options item is pressed
{
switch (item.ItemId)
{
case Resource.Id.settingsItem:
showSettings ();
return true;
case Resource.Id.helpItem:
//do something
return true;
}
return base.OnOptionsItemSelected(item);
}
Any ideas on this would be appreciated. I'm sure it's something fairly simple but I don't know what.
You should probably have to clear the menu
public override bool OnPrepareOptionsMenu(IMenu menu1)
{
menu1.clear();
MenuInflater.Inflate(Resource.Menu.myMenuBar, menu1);
return base.OnPrepareOptionsMenu(menu1);
}
And perhaps you should inflate the menu in the OnCreateOptionsMenu(IMenu, MenuInflater) method. OnPrepareOptionsMenu(IMenu) is meant for enabling/disabling and dynamically modifying items.
Related
I am new to android. I know this question have been asked before but, i am still confuse . What this method does when returning them inside my onCreateOptionMenu() and onOptionItemSelected()
Can any one help me what effect i will have
1)if i return true
2)if i return false
3)What will happen when i return super.onCreateOptionMenu() and super.onOptionItemSelected
Can anyone please explain me this with good example. I am still confuse.
Ok, let's first see the two methods of your interest
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
if return true ==>>> It means you want to see the option menu which you have inflated.
if return false ==>>> you do not want to show it
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
// Activate the navigation drawer toggle
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
As per documentation
true --> Event Consumed now It should not be forwarded for other event
false --> Forward for other to consume
This Boolean return type actually benefits when we are working with multiple fragments and every fragment has their own Option menu and Overriding of OnOptionItemSelected(Mainly in tablet design)
In this case android trace every fragments OnOptionItemSelected method so to avoid that
a) If any fragment is consuming event in onOptionsItemSelected() so return "true" else return "false"
b) If We return false then It will trace other connected fragment's (onOptionsItemSelected)
method until it ends all fragment or Somebody consumes It.
And your 3rd answer is as KrishnaJ written
super.onCreateOptionMenu() and super.onOptionItemSelected
If you write this then It will first call your parent class this method If you extend any class in this class.It will work as parent class if Methods are in parent class too.
Ok. I got you question:
Que 1 :
What this method does when returning them inside my onCreateOptionMenu() and onOptionItemSelected()
Ans :
onCreateOptionMenu() used for inflate menu in action bar.
onOptionItemSelected() used for capture onclick of that menus
Que 2 :
if i return true or false
Ans :
ref !!! you should return true if you have inflated menu in that file or your defined menu is clicked. else u should return false. so compiler will find for men or menu item in other page.
eg. you have one activity and two fragment, then if menu or menu item not find in activity then compiler will find it in fragment. if you return true then no further search.
Que 3 :
why to use super ?
Ans :
so compiler get to know that in this file there is no user defined menu or item value.
onCreateOptionMenu() method used to create an option menu.
onOptionsItemSelected() method used to handling the event of option menu i.e. which menu action is triggered and what should be the outcome of that action etc.
I like to add your 3rd question answer in answer of Dnyanesh
super.onCreateOptionMenu() and super.onOptionItemSelected
If you write this then It will first call your parent class this method If you extend any class in this class.It will work as parent class if Methods are in parent class too.
I am using navigation component to navigate between my fragments. I have 1 fragment where the user can edit some data. As soon as anything changes i set the flag "saved = false" and after user presses "save" button, flag goes to "saved = true". Now, what i want to do, is to add a usual popup message (Do u want to save the changes? Yes No Cancel) when the user pressed a back button, but did not save the changes. Also i want to add it to both buttons:
This one
And this one
I looked into this: https://developer.android.com/guide/navigation/navigation-custom-back
and it works only for (main) back button, but not for the one on the toolbar. When i need to go to previous fragment in code i use:
findNavController().popBackStack()
So do i need to somehow override this function or add a callback? Or maybe there is some entirely different (better) way of doing this?
Next time plz share your code.
I had the same problem and this is my solution, You need to override onOptionsItemSelected in your activity/fragment and to check when "back" arrow is pressed.
Code
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// put here what you would like to happen when u click on it
return true;
default:
return super.onOptionsItemSelected(item);
}
}
EDIT : I just notice that you are using Kotlin so i added a kotlin example:
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.getItemId()){
android.R.id.home -> {
// put your code here
return true
}
}
return super.onOptionsItemSelected(item)
}
Feel free to ask anything:)
I am new to android. I know this question have been asked before but, i am still confuse . What this method does when returning them inside my onCreateOptionMenu() and onOptionItemSelected()
Can any one help me what effect i will have
1)if i return true
2)if i return false
3)What will happen when i return super.onCreateOptionMenu() and super.onOptionItemSelected
Can anyone please explain me this with good example. I am still confuse.
Ok, let's first see the two methods of your interest
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
if return true ==>>> It means you want to see the option menu which you have inflated.
if return false ==>>> you do not want to show it
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
// Activate the navigation drawer toggle
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
As per documentation
true --> Event Consumed now It should not be forwarded for other event
false --> Forward for other to consume
This Boolean return type actually benefits when we are working with multiple fragments and every fragment has their own Option menu and Overriding of OnOptionItemSelected(Mainly in tablet design)
In this case android trace every fragments OnOptionItemSelected method so to avoid that
a) If any fragment is consuming event in onOptionsItemSelected() so return "true" else return "false"
b) If We return false then It will trace other connected fragment's (onOptionsItemSelected)
method until it ends all fragment or Somebody consumes It.
And your 3rd answer is as KrishnaJ written
super.onCreateOptionMenu() and super.onOptionItemSelected
If you write this then It will first call your parent class this method If you extend any class in this class.It will work as parent class if Methods are in parent class too.
Ok. I got you question:
Que 1 :
What this method does when returning them inside my onCreateOptionMenu() and onOptionItemSelected()
Ans :
onCreateOptionMenu() used for inflate menu in action bar.
onOptionItemSelected() used for capture onclick of that menus
Que 2 :
if i return true or false
Ans :
ref !!! you should return true if you have inflated menu in that file or your defined menu is clicked. else u should return false. so compiler will find for men or menu item in other page.
eg. you have one activity and two fragment, then if menu or menu item not find in activity then compiler will find it in fragment. if you return true then no further search.
Que 3 :
why to use super ?
Ans :
so compiler get to know that in this file there is no user defined menu or item value.
onCreateOptionMenu() method used to create an option menu.
onOptionsItemSelected() method used to handling the event of option menu i.e. which menu action is triggered and what should be the outcome of that action etc.
I like to add your 3rd question answer in answer of Dnyanesh
super.onCreateOptionMenu() and super.onOptionItemSelected
If you write this then It will first call your parent class this method If you extend any class in this class.It will work as parent class if Methods are in parent class too.
When transitioning between pages, each fragment page shares the same menu options. The menu option contains button which launches an activity. That activity is highly dependent on the information the current page item shows.
I noticed that when I change the view such that, the next page is almost shown on the screen (not fully transitioned) and I select the option for that item, the options shows the data from the previous item. I think this is because, he transition between pages was not fully complete. This is kind of confusing for my users. There could be people who swipe faster and press the option button. I noticed then when swiping between fragments and then suddenly press the menu option. The options shows the data from the previously active page.
If I could only hide the menu options, and only show it when the page is fully transitioned, I believe I can solve this problem. Or else, maybe I am doing something wrong which could have averted this in the first place?
I am using FragmentStatePagerAdapter.
Thank you!
Use ViewPager.SimpleOnPageChangeListener and when the onPageScrollStateChanged event is triggered check to see the state of the scroll if is idle then the page is in view and active (allow user to press the menu button), if is in another state then lock/hide the menu buttons.
I think I was able to solve my problem. I created an interface on my fragment which the hosting activity has to implement:
public interface OnOptionsMenuEnabledListener{ public boolean onOptionsMenuEnabledListener(); }
The hosting activity will just return a flag indicating if the menu is enabled.
#Override
public boolean onOptionsMenuEnabledListener()
{
return mOptionsEnabled;
}
And set the flag via ViewPager.onPageScrollStateChanged (int state):
#Override
public void onPageScrollStateChanged(int state)
{
switch(state)
{
case ViewPager.SCROLL_STATE_IDLE:
mOptionsEnabled = true;
break;
case ViewPager.SCROLL_STATE_DRAGGING:
mOptionsEnabled = false;
break;
case ViewPager.SCROLL_STATE_SETTLING:
mOptionsEnabled = true;
break;
}
}
Every time the option is being selected during screen transition, I call the interface method to communicate to me what the status of the flag:
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
boolean enable = true;
if(mOnOptionsMenuEnabledListener != null)
{
enable = mOnOptionsMenuEnabledListener.onOptionsMenuEnabledListener();
}
if(enable)
{
...
// select your menu items
}
return true;
}
So in this approach, the menu is still there (which is a big plus). But the option menu doesn't react until it settles down on a particular page.
With this I no longer encounter the problem.
I hope this help someone in the future!
Cheers!
When the button is clicked check ViewPagers current item -
https://developer.android.com/reference/android/support/v4/view/ViewPager.html#getCurrentItem()
YourObject object = yourList.get(yourViewPager.getCurrentItem());
I This is from https://developers.facebook.com/docs/android/scrumptious/authenticate
This is my code (identical from the tutorial) for the options menu part
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// only add the menu when the selection fragment is showing
if (fragments[SELECTION].isVisible()) {
if (menu.size() == 0) {
settings = menu.add(R.string.settings);
}
return true;
} else {
menu.clear();
settings = null;
}
return false;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
if (item.equals(settings)) {
showFragment(SETTINGS, true);
return true;
}
return false;
}
whats happening is this works most of the time but I found a test case I couldn't debug. When you logout, the menu item still shows and you have to click it to make it disappear.(it shouldn't appear at all). This wasn't a huge concern to me at the beginning but I found that when you logged in again after you clicked the menu item to make it disappear, the options menu doesn't appear at all.
I think I found the problem, I leave it up for others. From When and how often onPrepareOptionsMenu() method is called for ActionBar? ,I got that "On Android 3.0 and higher, you must call invalidateOptionsMenu() when you want to update the menu, because the menu is always open. The system will then call onPrepareOptionsMenu() so you can update the menu items."
When I logged out, even thought there were no actual menu items, the menu was still open. However when I clicked the menu when it was empty, it messed it up so that when I logged in, show wouldn't work. I don't understand that part yet. I was hoping someone can elaborate what happened during that part