Toolbar Menu showing in wrong fragment - android

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.

Related

App's hierarchy within bottom navigation bar

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.

How to update toolbar options from Fragment

I am having a tablayout, navigationdrawer and toolbar in an activity.
Added 3 fragments to viewpager and added viewpager to tablayout:
Code snippet of my activity:
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
Now in each fragment I have to display different options in toolbar:
So I tried to access the toolbar in my fragment like this:
public View onCreateView(LayoutInflater inflater,
#Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
_context = getActivity();
mainView = inflater.inflate(R.layout.frag1, container, false);
mToolbar =(Toolbar) mainView.findViewById(R.id.app_bar);
mToolbar.setTitle("");
toolbarTitle = (TextView) getActivity().findViewById(R.id.toolbar_title);
toolbarTitle.setText("Fragment1");
toolbarTitle.setSelected(true);
AppCompatActivity activity = (AppCompatActivity) getActivity();
activity.setSupportActionBar(mToolbar);
}
Inflated the required menu in onCreateOptionsMenu(Menu menu, MenuInflater inflater)
but not inflating as required the menu in toolbar. How can we change the toolbar options in Fragment.
This is working for me. This is all I have in onCreate. (Refreshable is an interface of my own).
public class SummaryFragment extends Fragment implements Refreshable {
#Override
public void onCreate(Bundle savedInstanceState) {
setHasOptionsMenu(true);
super.onCreate(savedInstanceState);
}
And this is where I inflate the menu.
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.save, menu);
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.save:
{
File csvFile = saveResults();
etc...
It's gone now, but I even had a different menu in my MainActivity and the two were both present when my Summary tab was active.

Fragment's menu multiplates itself on screen rotate

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.

Changing the menu when switching one activity to another activity

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));
}
}

Add data to a listview on fragment

I have an fragment on activity, with an listview element on it. Can't add data to listview. Can someone tell me what is wrong?
public class MainActivity extends FragmentActivity {
public String[] listS ={"item1","item2","item3"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
MainFragment f = new MainFragment();
ft.replace(R.id.fragcontainer, f);
ft.commit();
//here the problem occurs
ListView lv = (ListView)findViewById(R.id.listf);
lv.setAdapter(new ArrayAdapter<String>(this, R.layout.list_row,R.id.labeld, listS));
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
Fragment's class:
public class MainFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sis){
return inflater.inflate(R.layout.fragment_layout, container, false);
}
}
There's a number of problems with this method, but the root of it is that the FragmentTransaction replace() method that adds the fragment that, I assume, contains the ListView you're trying to find is an asynchronous process. The fragment isn't added to the Activity's view hierarchy immediately but some time later.
If you want to add things to a ListView in a Fragment, why not do it from within the MainFragment subclass' onCreateView() method instead? That's how it's intended to work.
EDIT: A typical onCreateView():
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_layout, container, false);
ListView lv = (ListView) view.findViewById(R.id.listf);
lv.setAdapter(new ArrayAdapter<String>(this, R.layout.list_row,R.id.labeld, listS));
return view;
}
When u add code for define your class,
public class MainFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sis) {
View view = inflater.inflate(R.layout.my_fragment, container, false);
ListView listView = (ListView) view.findViewById(R.id.list);
return view;
}
}
The problem is that you are asking to the activity for that ListView
"this."findViewById(...
You can ask the fragment for the view, or managing the content of the listView inside your Fragment class.
Please use the list view in the design windows as below. I faced the exact problem and now i could able to find the view in source code.
The main issue is IDE is appending "android" infront of ID
<ListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>

Categories

Resources