Using Options Menu in a multi-Fragment Activity - android

I have a FragmentActivity which hosts a FragmentStatePagerAdapter. The pager contains multiple instances of the same fragment, in order that the user can swipe between the items in a list. I want to be able to provide the user with an options menu which will act only on the visible item.
For example, I have a list of images displayed in imageviews inside fragments. I want an option menu item allowing the user to set the image as their wallpaper.
At the moment when I try this, when onPrepareOptionsMenu is called, the code is called in multiple fragments (usually the current + next one). The same when an item is selected. This causes the wrong image to be set as the wallpaper.
How can I prevent the options menu triggering for more than the currently visible fragment?

My solution was to use the setOnPageChangeListener method of the ViewPager in order to keep track of which Fragment index was currently visible with the onPageSelected callback. You still have to get the initial index yourself, but in my case this was trivial

You can intercept the options menu callback in the activity's onOptionsItemSelected, and explicitly call the item from the correct fragment there, returning true to indicate that you've handled it.

The trick is to change sethasoptions( true|false) on each fragment before populating menu. This already helped me

Related

How do I correctly mark an item as selected in the NavigationDrawer?

I have a navigation drawer in my app. Every Entry in the list of the NavigationDrawer represents one navigation graph. I want to mark the element in which the user currently is.
I managed to get the item to be marked after it is selected and until the visible fragment changes (even if the new fragment is still in the same navGraph). I did that by setting a NavigationItemSelectedListener using NavigationView.setNavigationItemSelectedListener(NavigationView.OnNavigationItemSelectedListener listener). Inside this listeners onNavigationItemSelected(item: MenuItem): Boolean function, I do: item.isChecked = true.
The problem with this is that the item is unchecked after the app starts and the item looses it's checked state as soon as the fragment changes (even if the navGraph doesn't change). How do I do this correctly?
I have also tried to set android:checked="true" in the xml declaration of the menu item I want to be checked when the app starts. It doesn't seem to do anything.
I have also tried to set navView.setCheckedItem(R.id.main_nav_option_one) in the Activity's onCreate function. Again, it doesn't seem to do anything.
Can you try
navView.getMenu().getItem(index).setChecked(true)
in the fragment's onResume?
I managed to solve my problem.
The most important change I had to make is mentioned here. I had to give my menu items the same ID as the ID of the navGraphs. When I did this, I removed my NavigationItemSelectedListener because it was interfering with the automatically generated navigation. Without a NavigationItemSelectedListener I could no longer handle a navigation item being clicked, that doesn't have a corresponding element in the navGraph. However I was able to fix it, by adding the NavigationItemSelectedListener back in, and making the correct calls to NavController.navigate() for every element in the list.
TL;DR:
I had to set the menu item IDs to be the same as my navGraph IDs and make the navigation calls myself anyway in the NavigationItemSelectedListener.

Android Menu duplication fixed with clear but it clears the parent activity menu

I have created different fragment and populated some menu based on the fragment. I was getting duplicate menu items so I used clear as suggested various stackoveflow posts but the problem is when I use clear in fragment it also clears the main activity menu items.
Activity and all fragments inside it use the same Menu instance. So no matter where you call clear() method, all items will be deleted.
Menu items that are used across all child fragments should be created inside Activity. Fragment-specific options should be created inside corresponding fragment. Ideally you should not have duplicated menu items. If two fragments have same menu item but third doesn't -- prefer create menu item inside every fragment but not single menu item inside activity. With this approach you will not get duplicates.
But If you want just to delete duplicates you can use menu.removeItem(itemId) method. Also you can hide redundant item with menuItem.setVisible(false).
When I switch between Fragments, I get duplicated menu
Maybe you have two active fragments at the same time. It can be when you use add method instead replace.

Action bar title change on item selection - where?

I am developing an Android application and I have the standard list and details implemented with fragments. In case that only one pane is shown, I want to dynamically set the action bar title after transition depending on the selected item. Where should I do that?
I have already put the index of the selected item in the intent and forwarded it to the fragment, so both detail activity and detail fragment know about it. Logically, I would set the title in the fragment, otherwise I have to deal with my content in the activity. However, I also have to check whether I am in one or two pane mode which is done in the activity. So, where is the right place for updating the title?
For me, updating the title (and everything related to the content) belongs to the fragment. I was first thinking about using an interface for invoking an updateTitle method of the fragment from the activity. Because of the high complexity for such a simple thing, I rejected the idea. Instead, I check in the fragment whether a detail fragment is displayed, in order to know whether there are one or two panes on the screen. After that, I simply invoke getActivity().setTitle(title) from the fragment with my title as parameter. This seems to be much shorter.
I would still appreciate each answer telling me what is the best practice in respect to this. But for now, my problem is solved.

Different menu for different fragments

I have an activity which has 2 fragments.
1 fragment is visible at a time and each fragment has a different option menu.
I can achieve this behavior by 2 different ways.
1 - I can add different menu for each fragment by calling onCreateOptionsMenu in each friengment.
2 - I can have only one menu at activity level and can select to show particular option in onPrepareOptionsMenu
What I want to know is:
Which is the preferable way to implement this functionality?
What is recommended?
Hope this helps
Adding items to the Action Bar
Your fragments can contribute menu items to the activity's Options Menu (and, consequently, the Action Bar) by implementing onCreateOptionsMenu(). In order for this method to receive calls, however, you must call setHasOptionsMenu() during onCreate(), to indicate that the fragment would like to add items to the Options Menu (otherwise, the fragment will not receive a call to onCreateOptionsMenu()).
Any items that you then add to the Options Menu from the fragment are appended to the existing menu items. The fragment also receives callbacks to onOptionsItemSelected() when a menu item is selected.
You can also register a view in your fragment layout to provide a context menu by calling registerForContextMenu(). When the user opens the context menu, the fragment receives a call to onCreateContextMenu(). When the user selects an item, the fragment receives a call to onContextItemSelected().
http://developer.android.com/guide/components/fragments.html
I would follow the first option as having a dedicated resource menu for each fragment seems cleaner and also reduces the code complexity you would have in order to maintain what is visible and what is not (if you would go through onPrepareOptionsMenu and have code to hide & show different menus).
If you have some actions in your fragments, then you could create a base fragment class that each of your fragments would extend from.

Android actionbar orientation change quirks - calling tabSeleceted & ItemSelected methods

I am working on a tablet application with two fragments on the main activity. The left fragment is a list fragment whose contents is updated when the user selects a tab or selects an item from 2 spinners within the ActionBar.
Originally I handled orientation change by overriding onConfigurationChanged. As this is not advised by Google and it causes issues with ActionBarSherlock, I have started work on doing it the right way. I have set my fragments to retain their instance (setRetainInstance) for orientation changes.
The problem is when the orientation changes the OnCreate method for the activity adds the tabs to the actionbar and selects one causing the list to reload. This also happens with the spinners as on rotation a new item is selected. On orientation change the list fragment has no need to refresh.
I know it is possible to save the tab and spinner state but how do I stop the list from updating as this is done in the onTabSelected and onItemSelected methods?
How about using onRetainNonConfigurationInstance() to save some state which should not change on orientation change? For example, if you follow #ThomasKJDK's answer , you could set the boolean in this method. You could then retrieve this boolean in onCreate(); and decide on execution of various code segments based on this boolean.
More details about this approach here.
I don't know if this is the proper way of doing it, but you could make a local variable (boolean) which is set after the first OnCreate and reset at OnPause/OnDestroy. You can then use the created variable to exclude execution of some code segments in the onCreate method.

Categories

Resources