I have a 3 page Fragment in my app, but I need each fragment to have a different ActionBar. For one fragment I have set the current code in the OnCreateView method that adds in an EditText to the ActionBar:
//mainActivityContext is the context for the Main Activity (This is a fragment file)
ActionBar actionBar = mainActivityContext.getActionBar();
// add the custom view to the action bar
actionBar.setCustomView(R.layout.actionbar_view);
search = (EditText) actionBar.getCustomView().findViewById(R.id.searchfield);
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM
| ActionBar.DISPLAY_SHOW_HOME);
Yet this EditText stays persistent throughout all of the ActionBar menus. I only want it on one. I have tried everything, menu.clear();, setHasOptionsMenu(true);, inflater.inflate(R.menu.different_file, menu);, but nothing has worked.
Any help?
There is a very good approach to go about this situation:
on each fragment's onActivityCreated() method call setHasOptionsMenu(true);
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
}
now you can override onCreateOptionsMenu() and onOptionsItemSelected() inside each fragment.
And also dont forget to call getActivity().supportInvalidateOptionsMenu(); inside onResume() of fragment.
I think this sample by google will be very helpful.
Since the actions are populated by the activity's options menu you can use Activity#invalidateOptionsMenu(). This will dump the current menu and call your activity's onCreateOptionsMenu/onPrepareOptionsMenu methods again to rebuild it.
If you're using action bar tabs to change your fragment configuration there's a better way. Have each fragment manage its own portion of the menu. These fragments should call setHasOptionsMenu(true). When fragments that have options menu items are added or removed the system will automatically invalidate the options menu and call to each fragment's onCreateOptionsMenu/onPrepareOptionsMenu methods in addition to the activity's. This way each fragment can manage its own items and you don't need to worry about performing menu switching by hand.
Related
I have given toolbar for each fragment in my app.
Following is code in the fragment to set toolbar. setToolbar is a method in Activity which is called from fragment using the interface.
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Toolbar toolbar = view.findViewById(R.id.toolbar);
if (mListener != null) {
mListener.setToolbar(toolbar);
}
}
Now since I am not removing toolbar when the fragment is destroyed it is causing a memory leak. I want to know where should I remove the toolbar fragment and how.
Any idea where and how should I release toolbar which is in the fragment?
As per my previously asked question Can I have toolbar for each fragment separately. How to handle navigation drawer I was told I can have a toolbar in each fragment but now I am facing memory leak.
Instead of creating toolbar for each fragment separately, create a single toolbar in the parent activity of those fragments.
If you are concerned about menu options in each fragment, then no need to worry. Just write setHasOptionsMenu(true) inside onCreateView method of each fragment. Also override onCreateOptionsMenu and onOptionsItemSelected in each fragment.
Activity toolbar will reflect the changes in menu options automatically.
NOTE: Always generate an activity from the template provided by Android Studio. It will save you both time and energy. You can always remove all the boiler plate code which you deem to be unnecessary.
The solution is to not set the toolbar for the activity. But if you want to, you can remove it in the Fragment.onStop().
If your toolbars look the same (component-wise), Have the Toolbar in your activity, and upon onAttach() of each fragment, pass the arguments like toolbar title, hasBack and ... to your activity and let the activity handle showing it.
This way you would never have a memory leak and also, everytime a fragment gets attached, the toolbar gets updated accordingly.
I suggest creating an interface like ToolbarInteractor and have two methods, setToolbar(title:String,hasBack:Boolean,...) and resetToolbar() and let your activity implement it. Then in your fragment, call ((ToolbarInteractor) getActivity()).setToolbar(...). Same goes for reset().
Yes, as above answer you can have one parent activity in which you can have toolbar implementation and the fragments are implemented in the same.
Now to customize your toolbar header you can implement a method interface and can use accordingly.
For brief & other option you may use this LINK
I have fragment which shows menu on action bar.
onPrepareOptionsMenu() is getting called after onCreateView()
Is that normal behavior? Is there any documentation that show this kind of stuff?
Yes its normal since onCreateView() first inflate the layout and then you can prepare the menu items and add listener to it.
Let's say I have a FragmentA visible.
I add a FragmentB (keyword: add, not replace), add it to the Fragment back stack and commit.
The issues I'm having doing this is:
1) The action buttons of the action menu of FragmentB are added, but those of FragmentA are not removed.
2) The title of the ActionBar does not change (despite calling getActivity().setTitle("FragmentB") in onResume() of FragmentB.
I can resolve both of these by calling replace instead of add when showing FragmentB however, for quite a few reasons I specifically need to add the Fragment instead (one of them being, I need to retain the state of FragmentA while showing B).
So how would I go about updating the ActionBar correctly as described?
Try this piece of code:
getActivity().getActionBar().setTitle("FragmentB");
Use this code in your Activity.. (for setting title to your fragment).
public void setActionBarTitle(String title) {
getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle(title);
}
from your fragment onResume(), call this using
// Set title bar
((MyActivity) getActivity())
.setActionBarTitle("Fragment A");
and in each fragment you need to override onCreateOptionsMenu() to load your menus of that fragment.
I am using a Custom FragmentPagerAdapter for SwipeViews in ActionBar.NAVIGATION_MODE_TABS mode.
I want the Fragments inside the adapter to provide their custom Menus. But I observed that onCreateOptionsMenu() method inside the Fragment is not getting called even when I used setHasOptionsMenu(true);
inside the onCreate() callback of the Fragment.
In short,How can I get custom Options Menu for each Fragment in ViewPager?
Please write the code in onCreateOptionsMenu & onPrepareOptionsMenu of your activity to inflate the from menu xml. You can then customize the menu in your fragment by using these functions inside your fragment again. I tried it and it worked for me.
Actually your problem seems to lie in ViewPager. Either its not instantiated properly or its Visibility is set to Visibility.GONE.
Make sure that ViewPager is Visible on screen by default or there is no code which changes its visibility. Get back to me if problem persists.
I need to make two minor changes to an Activity's ActionBar from a Fragment.
The parent FragmentActivity's onCreateOptionMenu and onPrepareOptions handle the menu across the app.
However, in the containing main Fragment view, I want the ActionBar title to change for the sake of navigation. Each time the Fragment changes.
Also, in one instance, I want to add a single menu item as defined in the layout. I rather not duplicate code for this part, do I have to override the same methods and set up entire menu again, including onOptionSelected? Or...?
Edit:
On my menu xml layout, I have this item:
<item
android:id="#+id/Add"
android:title="Add Items"/>
This item needs to be seen in the ActionBar only for one particular Fragment. The rest of the menu is identical to what should be seen for the rest of the app. In the fragment where I need this new item, do I have to also do onCreateOptionsMenu, onPrepareOptionsMenu, and onOptionsItemSelected all over again and duplicate thee OTHER menu items as well? Or can I override those in the Fragment and just pop that one extra menu item in?
1.
getActivity().getActionBar().setTitle();
or
getActivity.getSupportActionBar().setTitle();
more clarification please :)
This answered what I needed for part 2.
Putting this in onActivityCreated:
setHasOptionsMenu(true);
And then adding this too:
#Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
ActivityCompat.invalidateOptionsMenu(getActivity());
MenuItem Add = menu.findItem(R.id.Add);
Add.setVisible(true);
}
The parent Activity sets the R.id.Add as invisible by default.