I like to change menu when the activity is changed. I have MainActivity.java with activity_main.xml menu. Then I have MyDetailFragment.java with detail_view_menu.xml. The MainActivity menu is inflated in the onCreateOptionsMenu of MainActivity.java as
#Override
public boolean onCreateOptionsMenu(Menu menu) {
new MenuInflater(this).inflate(R.menu.activity_main, menu);
return (super.onCreateOptionsMenu(menu));
}
It works fine. When one of the items is tapped and the MyDetailFragment.java is loaded, I like to display detail_view_menu.xml. How I implement is
public class MyDetailsFragment extends Fragment {
TrackerInfo trackerInfo;
public MyDetailsFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.my_details_fragment, container, false);
setHasOptionsMenu(true);
TextView displayText = (TextView) view.findViewById(R.id.details);
displayText.setText(trackerInfo.getIdnumber());
return view;
}
public void retrieveData(TrackerInfo tracker){
trackerInfo = tracker;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.detail_view_menu, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.track:
return (true);
case R.id.view_history:
return (true);
}
return (super.onOptionsItemSelected(item));}}
But the problem is that the menu is still the same activity_main menu and never changed. What could be the problem?
You need to super call the same method.
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.detail_view_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
Once I had issue when the new menu items where appended to the menu. So I resolve it with removing all menu items before inflating new ones.
Like this:
public static void emptyFragmentOptionsMenu(Menu menu){
if(menu==null)return;
for(int i=0; i < menu.size(); i++)
menu.removeItem(menu.getItem(i).getItemId());
}
Cheers,
Edit: How I used the method:
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
emptyFragmentOptionsMenu(menu);
inflater.inflate(R.menu.detail_view_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
First: you should have an onCreate() method above your onCreateView() and there you set setHasOptionsMenu(true);
Second: you need to use super.onCreateOptionsMenu(menu, inflater); after the inflater in your onCreateOptionsMenu().
Third: you have just duplicated your question that you originally posted here. Please don't do that in the future. I have provided you with additional details on that question then you switched on this one. Next time just edit your original question. Otherwise you might just sabotage yourself and become annoying for those trying to help you.
Do this:
public class MyDetailsFragment extends Fragment {
TrackerInfo trackerInfo;
public MyDetailsFragment() {
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true); // this should go here not in onCreateView();
// ....
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.my_details_fragment, container, false);
TextView displayText = (TextView) view.findViewById(R.id.details);
displayText.setText(trackerInfo.getIdnumber());
return view;
}
public void retrieveData(TrackerInfo tracker){
trackerInfo = tracker;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.detail_view_menu, menu);
super.onCreateOptionsMenu(menu, inflater); // you need to call super
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.track:
return (true);
case R.id.view_history:
return (true);
}
return (super.onOptionsItemSelected(item));
}
}
Related
I want to implement menu in fragment class. The fragment works fine and there is not error but there is no menu shown in the fragment. I am implementing the class in the following way
public class FilesFragment extends Fragment {
public FilesFragment() {
// Required empty public constructor
}
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view = inflater.inflate(R.layout.fragment_files, container, false);
return view;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
setHasOptionsMenu(true);
super.onCreate(savedInstanceState);
}
#Override
public void onCreateOptionsMenu(#NonNull Menu menu, #NonNull MenuInflater inflater) {
inflater.inflate(R.menu.files_menu,menu);
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_setting){
Toast.makeText(getActivity(),"setting clicked",Toast.LENGTH_SHORT).show();
}
return super.onOptionsItemSelected(item);
}
}
and this is the xml file of files_menu in menu folder.
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/action_setting"
android:title="settings"
app:showAsAction="never"/>
<item
android:id="#+id/aobut"
android:title="About"
app:showAsAction="never"
/>
</menu>
The above code is not showing the menu at all. How do menu is implemented in the fragment?
You can populate the menu in any view without any complexity. Use the following code and enjoy.
any View can be a button , imageView or any other else in which you want to inflate this menu. No need to add menu in xml. Just do in java
PopupMenu popup = new PopupMenu(context, any View);
popup.inflate(R.menu.files_menu );
popup.setOnMenuItemClickListener(item -> {
int id = item.getItemId();
if (id == R.id.action_setting) {
// do stuff
} else if (id == R.id.aobut) {
//
}
return true;
});
popup.show();
I want to implement bottomNavigationBar. in that when i click on any item within fragment, it should open new view with bottomNavigationBar at bottom and back button on top like below screen.
there is also other example from below link:
View
in that, you can see you-tube did same thing with searchView. help me how can i do that.
Try this
#Override
. public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState)
{
View v = inflater.inflate(R.layout.fragmet_search, parent, false);
return v;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.your_search_menu_xml, menu);
super.onCreateOptionsMenu(menu, inflater);
}
#FAT Suggestions Refer here
This may help you.
My main_activity have 2 fragments -> Parent and Child as follow :
https://imgur.com/ws9BRWR
each fragment should have their own actionbar and their own menu.
my question are : why is the menu that supposedly shown in child fragment mixed together into the parent fragment?
Child-Menu-1 and Child-Menu-2 supposed to be inside menu in child fragment
this is what i have done :
fragmentParent :
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_parent, container, false);
setHasOptionsMenu(true);
Toolbar myToolbar = (Toolbar) view.findViewById(R.id.tb_parent);
((AppCompatActivity)getActivity()).setSupportActionBar(myToolbar);
((AppCompatActivity)getActivity()).getSupportActionBar().setTitle("PARENT");
//((AppCompatActivity)getActivity()).getSupportActionBar().setDisplayShowTitleEnabled(false);
return view;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.menu_parent, menu);
}
fragmentChild :
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_child, container, false);
setHasOptionsMenu(true);
Toolbar myToolbar = (Toolbar) view.findViewById(R.id.tb_child);
((AppCompatActivity)getActivity()).setSupportActionBar(myToolbar);
((AppCompatActivity)getActivity()).getSupportActionBar().setTitle("CHILD");
//((AppCompatActivity)getActivity()).getSupportActionBar().setDisplayShowTitleEnabled(false);
return view;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.menu_child, menu);
}
what i have tried already :
move the getSupportActionBar into onViewCreated <--- same result
move the inflate to onPrepareOptionsMenu <--- same result
i noticed that if i remove the menu from the parent fragment, the menu on the child show up correctly, problem only if i try to load each with their own menu.
when i debug the apps, the sequence called are :
calling child fragment onCreateView
calling parent fragment onCreateView
calling child onCreateOptionsMenu
calling parent onCreateOptionsMenu
so i'm suspecting the problem is in the onCreateOptionMenu where the inflater inflate the wrong fragment.
i already do a lot of searching inside SO and google, but no question seems similar to my case.
thank you very much in advance!!
==========================================================================
further examination and testing... so i commented out the creating of the toolbar from the parent fragment :
fragmentParent :
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_parent, container, false);
setHasOptionsMenu(true);
//Toolbar myToolbar = (Toolbar) view.findViewById(R.id.tb_parent);
//((AppCompatActivity)getActivity()).setSupportActionBar(myToolbar);
//((AppCompatActivity)getActivity()).getSupportActionBar().setTitle("PARENT");
//((AppCompatActivity)getActivity()).getSupportActionBar().setDisplayShowTitleEnabled(false);
return view;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.menu_parent, menu);
}
fragmentChild :
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_child, container, false);
setHasOptionsMenu(true);
Toolbar myToolbar = (Toolbar) view.findViewById(R.id.tb_child);
((AppCompatActivity)getActivity()).setSupportActionBar(myToolbar);
((AppCompatActivity)getActivity()).getSupportActionBar().setTitle("CHILD");
//((AppCompatActivity)getActivity()).getSupportActionBar().setDisplayShowTitleEnabled(false);
return view;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.menu_child, menu);
}
Result :
https://imgur.com/wYVdsvH
all menu item show up in the child fragment, why is the parent fragment onCreateOptionMenu getting called while there's no toolbar is declared?
i'm hitting wall here :(
Have you tried calling invalidateOptionsMenu() after you've added or replaced the Fragment?
I found the answer from this link:
Set menus for multiple toolbars on android
If we running multiple toolbar menu within 1 activity (even in different fragment in my case)
for the first toolbar, inflate is from onCreateOptionsMenu(), and callback is from onOptionsItemSelected()
for the second toolbar, via we need to inflate the second menu toolbar and set the callback manually:
toolbar2 = (Toolbar) findViewById(R.id.tool_bar_bottom);
toolbar2.inflateMenu(R.menu.bottom_menu);//changed
toolbar2.setOnMenuItemClickListener(new OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem arg0) {
if(arg0.getItemId() == R.id.item_id){
}
return false;
}
});
Thank you #skadoosh.
I have a fragment which has a menu with one item. The problem is on every screen orientation change this item is doubled. So there is 2 (the same) items after first screen change, 3 items after second change and so on...
public class ManageLinksFragment extends Fragment {
FragmentManager fragmentManager;
FragmentTransaction fragmentTransaction;
DBHttpLinks db;
long itemPosition;
SimpleCursorAdapter adapter;
ListView lv;
Listener mListener;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
setRetainInstance(true);
setHasOptionsMenu(true);
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.chooseonelinkfragment, container, false);
lv = (ListView) v.findViewById(R.id.listView1);
return v;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_links, menu);
super.onCreateOptionsMenu(menu,inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.addlinks:
fragmentManager = getFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
// AddNewRecordFragment is a class name!
AddHttpLinksFragment fragment2 = new AddHttpLinksFragment();
fragmentTransaction.replace(R.id.fragment_left, fragment2, "addlinksF");
fragmentTransaction.addToBackStack("chooselinksF");
fragmentTransaction.commit();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getActivity().getMenuInflater();
inflater.inflate(R.menu.context_menu_manage_links, menu);
}
}
Try moving :
setHasOptionsMenu(true);
setRetainInstance(true);
to your fragment onCreate,
also, make sure you are not adding your fragment in Activity.onCreate, even if it already exists.
I'm using fragments and I have a menu item in one of my fragments. The fragment that uses the menu item is called when an item in the List View is clicked. When the fragment with the menu item is called, and then I change the tab, the menu item is still there. I want the menu item to only show in the one fragment only.
Here is the code for Tab 1
public class Tab2Fragment extends Fragment{
#Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setHasOptionsMenu(false);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.tab_fragment, null);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getActivity().setTitle("Tab 2");
initView();
}
private void initView() {
((TextView)getView().findViewById(R.id.tab_text)).setText("Tab 2");
Button button = (Button) getView().findViewById(R.id.tab_btn);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
replaceFragment();
}
});
}
private void replaceFragment() {
((BaseContainerFragment)getParentFragment()).replaceFragment(new Tab2AddOnFragment(), true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){
inflater.inflate(R.menu.main, menu);
super.onCreateOptionsMenu(menu, inflater);
}
}
and Here is the code for Tab 3 which has the List View
public class Tab3Fragment extends ListFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setHasOptionsMenu(false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
String[] values = new String[] { "Ang na Ang na", "Sulakihin", "Somaskidot", "Moko Moko"};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, values);
setListAdapter(adapter);
getActivity().setTitle("Tab 3");
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
switch(position){
case 0:
// Create new fragment and transaction
FragmentTransaction transaction = getFragmentManager().beginTransaction();
replaceFragment();
transaction.setTransitionStyle(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
// Commit the transaction
transaction.commit();
break;
default:
}
}
private void replaceFragment() {
((BaseContainerFragment)getParentFragment()).replaceFragment(new FragmentInListView(), true);
}
}
and here is the code for the fragment with the menu item
public class FragmentInListView extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
getActivity().setTitle("Fragment Called in Tab 3(List View)");
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View view = inflater.inflate(R.layout.tab_fragment,
container, false);
TextView tv= (TextView) view.findViewById(R.id.tab_text);
tv.setText("Fragment in List View");
return view;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){
inflater.inflate(R.menu.travel_tips_expanded, menu);
super.onCreateOptionsMenu(menu, inflater);
}
}
and here is the code for the menu of the fragment with a menu item
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/action_settings"
android:orderInCategory="100"
android:showAsAction="never"
android:title="#string/action_settings"/>
<item
android:id="#+id/favorite"
android:showAsAction="always"
android:title="favorite"/>
Here is an image of the Fragment called when an item in the List View is clicked. And it contains the menu item.
http://s904.photobucket.com/user/fookywooky/media/tab4_zps30944a6e.png.html
And here is an image of the Fragment called when "Tab 2" is selected. As you can see, the menu item is still there but i don't want it to be there. Also, this is the case even if you click Tab 1 and Tab 3. The menu item is still there.
http://s904.photobucket.com/user/fookywooky/media/tab5_zps285c8314.png.html
Please help. Thanks in advance.
In order to accurately determine when to show the Fragment menu, your Activity needs some indication as to which Fragment is visible and current. You can accomplish this with the setMenuVisibility() and setUserVisibleHint() methods. In your OnTabChanged() callback, set the menu visibility and user visible hint to false in the previously selected Fragment and true in the currently selected Fragment.