Closed dkisselev closed 9 years ago
Ok, so I've figured out that the reason that nothing was working for me was that onNavigationDrawerItemSelected
is actually called for the first time before the View is inflated, which is why getSupportActionBar along with everything else was returning null.
I've solved that problem like so (put this under the Toast.makeText line in MainActivity.java):
if (getSupportActionBar() != null) {
getSupportActionBar().setTitle("Menu item " + position);
}
But now I'm wondering how to go further to build out some real functionality.
My main question now is whether this would be the correct place to put more complicated logic (like actually using the position in a switch statement to set fragments), or if it belongs in the Adapter or another class.
Yes, the onNavigationDrawerItemSelected
is where you should put almost all your logic. This template is the same as the one from Android Studio when you start a new application and selected the drawer template. So if you didn't used it before this is an example of how your onNavigationDrawerItemSelected
should look like (taken from one of my apps):
if (position == 0) {
if (getFragmentManager().findFragmentByTag("search") != null) return;
FragmentTransaction t = getFragmentManager().beginTransaction();
t.setCustomAnimations(R.anim.alpha_intro, R.anim.alpha_outro, R.anim.alpha_intro, R.anim.alpha_outro);
SearchFragment fragment = new SearchFragment();
t.replace(R.id.container, fragment, "search");
t.commit();
} else if (position == 2) { //favorites
if (getFragmentManager().findFragmentByTag("favorites") != null) return;
FragmentTransaction t = getFragmentManager().beginTransaction();
t.setCustomAnimations(R.anim.alpha_intro, R.anim.alpha_outro, R.anim.alpha_intro, R.anim.alpha_outro);
FavoritesFragment fragment = new FavoritesFragment();
t.replace(R.id.container, fragment, "favorites");
t.commit();
}
So as you can see in this example all the switch logic between fragments takes place here. Keep in mind that the first fragment is always selected when the app starts.
Also if you want to communicate with the drawer fragment you have mNavigationDrawerFragment
on your main activity that allows you to perform operations like menu item changes and such.
If you have further questions feel free to ask them here. If not, please mark this issue as closed.
Have a nice day.
Awesome, thanks, that really helps.
The one follow-up question to that is how I would set the toolbar title. I'm guessing that the title setting logic more of a function of how the drawer itself works rather than something that the onNavigationDrawerItemSelected
function handles (When drawer is open, the title should be the name of the app, when closed it should be the current tab name), but I'm unsure about how I would get access to the actionbar to call setTitle on it from within the NavigationFragment or Adapter.
In Google's navigationdrawer example (I did look at it before, but didn't see the resemblance at first so thought your implementation was different/from scratch), the mainactivity extends from the Activity class, where they just override/call setTitle:
@Override
public void setTitle(CharSequence title) {
mTitle = title;
getActionBar().setTitle(mTitle);
}
But it doesn't look like setTitle exists in ActionBarActivity
Thanks!
You have two ways of doing this:
@Override
public void onNavigationDrawerItemSelected(int position) {
Toast.makeText(this, "Menu item selected -> " + position, Toast.LENGTH_SHORT).show();
if (mToolbar != null)
mToolbar.setTitle("Menu Item " + position);
}
Or
@Override
public void onNavigationDrawerItemSelected(int position) {
Toast.makeText(this, "Menu item selected -> " + position, Toast.LENGTH_SHORT).show();
if (getSupportActionBar() != null)
getSupportActionBar().setTitle("Menu Item " + position);
}
Notice the getSupportActionBar() != null
because at the time this is called the actionbar can be null. Another more hacky way of doing that could be:
@Override
public void onNavigationDrawerItemSelected(final int position) {
Toast.makeText(this, "Menu item selected -> " + position, Toast.LENGTH_SHORT).show();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if (getSupportActionBar() != null)
getSupportActionBar().setTitle("Menu Item " + position);
}
}, 100);
}
I ended up implementing it in the NavigationDrawerFragment,
In MainActivity.java:
@Override
public void setTitle(CharSequence mTitle)
{
if (getSupportActionBar() != null) {
getSupportActionBar().setTitle(mTitle);
}
}
Then in NavigationDrawerFragment.java:
public void setup(int fragmentId, DrawerLayout drawerLayout, Toolbar toolbar) {
mFragmentContainerView = getActivity().findViewById(fragmentId);
mDrawerLayout = drawerLayout;
mActionBarDrawerToggle = new ActionBarDrawerToggle(getActivity(), mDrawerLayout, toolbar, R.string.drawer_open, R.string.drawer_close) {
@Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
if (!isAdded()) return;
getActivity().setTitle(getResources().getStringArray(R.array.drawer_items)[mCurrentSelectedPosition]);
getActivity().invalidateOptionsMenu();
}
@Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
if (!isAdded()) return;
if (!mUserLearnedDrawer) {
mUserLearnedDrawer = true;
saveSharedSetting(getActivity(), PREF_USER_LEARNED_DRAWER, "true");
}
getActivity().setTitle(R.string.app_name);
getActivity().invalidateOptionsMenu();
}
};
(I listed the titles for my navigation entries in a string array so I can pull them from the position like that)
I think the only part I'm missing is to set the title when the app if first opened because getSupportActionBar does return null there, but that can probably be fixed by forcing the title in onCreate for the MainActivity.
Thanks, that helps all around, hopefully this thread helps someone else in the same spot as me in the future.
In this repo, when a navigation item is selected, the Main_activity just pops up a toast with that item's position, but I can't seem to figure out how to do more than that, things that actually affect the app's state.
Right now I'm looking to just change the Toolbar's title to the app title when the nav drawer is open, then to the title of the currently selected menu when it's closed (like Google Play Music),
I'm playing around with adding the code to
onNavigationDrawerItemSelected
(just for the second part of the problem), but get null pointers whenever I try to do something likegetSupportActionBar().setTitle("Menu item" + position);
Then extending on that, I'd like to be able to swap out the container frame's fragment when an item is selected. So if I have fragment_one and fragment_two, where would I go to define the code that says 'load fragment_one into container on menu 1 tap'?
Perhaps a more complete example of an app that's using this template would really help.
Thanks!