In my app, I need to change the menu of the navigationView, when I click on the header
First state
Second state
I wanted to get the currently active menu of my navigationView to toggle between the two menus. This is what I have written so far:
public void toggleMenu(){
navigationView.getMenu().clear();
navigationView.inflateMenu(R.menu.menu_trips);
}
Instead of inflating the same menu all the time, I need to create an if to inflate the menu which is not currently active, something like this:
if (navigationView == R.menu.menu_trips){
navigationView.inflateMenu(R.menu.activity_main_drawer);
} else if (navigationView == R.menu.activity_main_drawer){
navigationView.inflateMenu(R.menu.menu_trips);
}
I do not want to add an MenuItem, I just want to replace the menu. Clearing it and then inflating is the best option I found.
If you have a better solution, please tell me :)
You can not get menu id from Menu class.
I suggest you to keep a global variable that keeps your current menu id. Or you can compare first items to understand which menu is currently active.
Solved it:
String activeMenu;
protected void onCreate(){
activeMenu = "main";
}
public void toggleMenu(){
navigationView.getMenu().clear();
if (activeMenu.equals("main")){
navigationView.inflateMenu(R.menu.menu_trips);
activeMenu = "trips";
} else if (activeMenu.equals("trips")){
navigationView.inflateMenu(R.menu.activity_main_drawer);
activeMenu = "main";
}
}
Related
Generally switching from one activity to another activity hamburger icon is replaced with back arrow. I want to control the functionality of that arrow. I have seen many contents here but most of them were related to hardware's back button. How can I control that?
I am trying the functionality in case of fragments. Also I have Navigation drawer attached with the hamburger icon.
I tried this-
if(id == android.R.id.home){
getSupportFragmentManager().beginTransaction().replace(R.id.main_container, new AmbulanceMap()).commit();
getSupportActionBar().setTitle("Book A Ride");
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
}
but doesnt work as I hoped.
I want my back button to change the fragmentto previous fragment.
I had the same problem once. Just like you, things like checking if Android.R.id.home is clicked didn't work.
But I solved it using that:
Set navigation listener to toolbar:
toolbar.setToolbarNavigationClickListener(v -> onBackPressed());
If it should be within fragment:
Create an public method in activity.
In fragment's onAttach (or later) cast getActivity() to your activity and call method you was defined previously.
Example:
// YourActivity
public void setHomeListener(OnLickListener listener){
toolbar.setToolbarNavigationClickListener(listener);
}
//Fragment's onCreate
((YourActivity)getActivity()).setHomeListener(v -> onBackPressed());
//Fragment's onDestroy
((YourActivity)getActivity()).setHomeListener(null);
And, of course, set home us up enabled to show back arrow.
EDIT
if you don't use labmdas u should use:
(YourActivity)getActivity()).setHomeListener(new OnClickListener() {
#Override
public void onClick(View v) {
YourFragment.this.onBackPressed();
}
});
The back button of the ActionBar is a menuItem so you need to override onOptionsItemSelected like this:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case android.R.id.home:
//Your back button logic here
break;
}
return true;
}
Also donĀ“t forget to add getSupportActionBar().setDisplayHomeAsUpEnabled(true); after setting the Toolbar
When I created a new project I used Navigation Drawer Activity
app screen
Now each menu item when I click on it will open a fragment by calling a method name replacement.
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_home) {
replaceFragment(0);
setTit = "Your State Info.";
setTitle(setTit);
} else if (id == R.id.nav_flashcards) {
replaceFragment(1);
setTit = "Flash Cards";
setTitle(setTit);
in fragment 1 I have a RadioGroup when the checked change will open the fragmet depends on the radio checked.
#Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
RadioButton radioButton = (RadioButton)getActivity().findViewById(i);
if(radioButton.getTag()==1)
((MainActivity) getActivity()).replaceFragment(0);
else if ((radioButton.getTag()==2))
((MainActivity) getActivity()).replaceFragment(2);
}
The App work fine , but the issue is how can I change the Navigation Item Selected and also change the title for the action bar.
it's possible to use this way
((MainActivity) getActivity()).onNavigationItemSelected(menuitem);
but from the fragment how can I access the the items in the menu>activity_main_drawer.xml and pass it through menuitem
This works for me..
NavigationView navigationView = (NavigationView) getActivity().findViewById(R.id.nav_view);
navigationView.getMenu().getItem(2).setChecked(true);
In your fragment you have to add setOptionsMenu(true)
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// TODO Add your menu entries here
super.onCreateOptionsMenu(menu, inflater);
}
question is not clear.
whole point of navigation drawer with fragments is to access navigation and its main toolbar all over the fragments with a single main activity.(the blue color one in your image, you should be able to change this anytime when you load a fragment)
But you need to make the frame/parent view of the fragments blow the tool bar view(that's why normally it comes with two XMLs, activtyMain.xml and contentMain.xml where content main is included below the tool bar in activityMain.XML) so you create fragments view match_parent to this contentMain.xml ,you can see toolbar is accessible to the each and every fragment you add in that view because its in the main activity where fragment/s add.
so you have a main activity and inside that you have fragment/s frame. Doesn't matter what fragment you load you can still have the access to main toolbar.
so once you check which item got clicked in navigationDrawer you load the fragment related to that right?. and there access the main toolbar of the mainActivity and do the changes that you need to display.That's it!
if (id == R.id.nav_whatever) {
// access toolBar or any view in main activity and do the changes
// call relevant fragment
}
But you cannot access that toolbar or mainActivity views inside your Fragment class that you try to attempt.
Edit :
Keep a Boolean in a Constant class or something similar,
then when you click on your button on second fragment change the value .
Now let's say Boolean is true
Then you click the navigation drawer again
// keep the id as it is and use the Boolean to check where you needs to go
if (id == R.id.nav_whatever) {
if(boolianName){
// boolianName is true go load second fragment
}else{
// load firstfragment
}
}
If you use Navegation drawer, you can use this code, put it on onCreate method:
NavigationView navigationView = (NavigationView) getActivity().findViewById(R.id.nav_view);
navigationView.getMenu().getItem(2).setChecked(true);
I have a ViewPager where pages contain charting views which react to sliding movements. Due to this i resorted to changing the page by sliding from the edge of the screen. But that leaves me with the problem that this is also the gesture to open the NavigationDrawer.
Until now i used the following code to achieve this:
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(GetLayoutId());
Toolbar = FindViewById<Toolbar>(Resource.Id.toolbar);
if (Toolbar != null)
{
// set this flag so the colors colorPrimaryDark and android:statusBarColor have an effect
// setting android:statusBarColor to transparent causes the drawer to be dran underneath a translucent status bar
Window.AddFlags(WindowManagerFlags.DrawsSystemBarBackgrounds);
// make the toolbar the replacement of the action bar
SetSupportActionBar(Toolbar);
}
// add the hamburger icon
m_DrawerLayout = FindViewById<DrawerLayout>(Resource.Id.drawer_layout);
var actionBarDrawerToggle = new ActionBarDrawerToggle(this, m_DrawerLayout, Toolbar, Resource.String.empty, Resource.String.empty);
m_DrawerLayout.AddDrawerListener(actionBarDrawerToggle);
// make sure the drawer can't be opened by swiping, to do this we set the lock mode to closed
// but if we just do this, it can't be closed by swiping either, so set the lock mode to unlocked when the drawer is opened, and locked again when it's closed
m_DrawerLayout.DrawerOpened += (object sender, DrawerLayout.DrawerOpenedEventArgs e) =>
{
m_DrawerLayout.SetDrawerLockMode(DrawerLayout.LockModeUnlocked);
};
m_DrawerLayout.DrawerClosed += (object sender, DrawerLayout.DrawerClosedEventArgs e) =>
{
m_DrawerLayout.SetDrawerLockMode(DrawerLayout.LockModeLockedClosed);
};
m_DrawerLayout.SetDrawerLockMode(DrawerLayout.LockModeLockedClosed);
//calling sync state is necessay or else the hamburger icon wont show up
actionBarDrawerToggle.SyncState();
}
It worked as intended, until i updated to the Android Support Design Library 23.1.1.1, now setting the lock mode to closed also prevents the menu from being opened by tapping on the hamburger icon.
Looking at the source code for the latest version of the ActionBarDrawerToggle class, this does indeed seem to be the new intended behavior. It's toggle() method now looks like this:
private void toggle() {
int drawerLockMode = mDrawerLayout.getDrawerLockMode(GravityCompat.START);
if (mDrawerLayout.isDrawerVisible(GravityCompat.START)
&& (drawerLockMode != DrawerLayout.LOCK_MODE_LOCKED_OPEN)) {
mDrawerLayout.closeDrawer(GravityCompat.START);
}
else if (drawerLockMode != DrawerLayout.LOCK_MODE_LOCKED_CLOSED) {
mDrawerLayout.openDrawer(GravityCompat.START);
}
}
whereas it previously just checked the drawer's opened/closed state.
This is unfortunate, since it will now take a workaround to achieve the old behavior. Perhaps the simplest thing to do is just to revert to an older version of the support library. However, if you want to keep the newest version, one possible solution is as follows.
First remove the Toolbar argument from the ActionBarDrawerToggle constructor call.
actionBarDrawerToggle = new ActionBarDrawerToggle(this,
m_DrawerLayout,
Resource.String.empty,
Resource.String.empty);
This will cause the Activity's OnOptionsItemSelected() method to fire upon clicking the toggle, since you've set the Toolbar as the support ActionBar. We will also need to call SupportActionBar.SetDisplayHomeAsUpEnabled(true) to actually show the toggle, since the ActionBarDrawerToggle class interacts somewhat differently with an ActionBar than it does with a Toolbar, with respect to their child Views.
In the Activity's OnOptionsItemSelected() method, we then simply unlock the drawer before calling the toggle's own OnOptionsItemSelected() method, which handles the opening and closing of the drawer.
public override bool OnOptionsItemSelected (IMenuItem item)
{
switch (item.ItemId)
{
case Android.Resource.Id.Home:
m_DrawerLayout.SetDrawerLockMode(DrawerLayout.LockModeUnlocked);
actionBarDrawerToggle.OnOptionsItemSelected(item);
return true;
...
}
...
}
Your actionBarDrawerToggle will need to be a field of your Activity, and you can remove the DrawerOpened handler.
I implemented the new NavigationView (from the support library) and a couple of Fragments, I then overrided the onBackPressed function and added this:
getFragmentManager().popBackStack();
which returns me to the previous fragment.
So what I need is this: how I can change the navigationview's current selected item to the Fragment it is popping back to?
Finally i got it,
Firstly, i made the instance of the navigation global and public.
public NavigationView navigationview;
I then added in the onCreate and onResume of my fragment:
NavigationView navigationView = ((MainActivity) getActivity()).navigationview;
navigationView.getMenu().getItem(index).setChecked(true);
and the onResume:
navigationView.getMenu().getItem(index).setChecked(true);
This solved my problem, Hope this helps someone.
I know this is a little late but I found a solution that is maybe a little faster to code for Activities that have a large amount of fragments.
(In your activity)
Implement FragmentManager.OnBackStackChangedListener
In onCreate() add fragmentManager.addOnBackStackChangedListener(this);
Add Method from interface...
#Override
public void onBackStackChanged() {
MainActivityFragment f = (MainActivityFragment) fragmentManager.findFragmentById(R.id.fragment_container);
//Log.v(TAG, "OnBackStackChanged to fragment with index: " + f.getMenuIndex());
navigationView.getMenu().getItem(f.getMenuIndex()).setChecked(true);
}
(Create an interface in a separate file, name it MainActivityFragment) or whatever your activity is named.
public interface MainActivityFragment {
int getMenuIndex();
}
(All fragments that are used in that Activity)
Implement MainActivityFragment
Add Method from interface...
#Override
public int getMenuIndex() {
return 2;
}
It may seem like some extra work but in the long run it makes it pretty easy as all you have to do for new Fragments is implement the Activity's Interface and return the index of it's menu item.
Is there a way to animate the default 3-vertical-dotted menu icon on toolbar?
I use toolbar as actionbar with the standard code:
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
and I also use the onCreateOptionsMenu method inside activity where I inflate my menu.xml file
but I don't know how to gain more control over the overflow icon which is created automatically. What I'm most interested in is how to reference the menu icon So I can animate it. I don't care about the animation type. It can be a simple rotation animation
Well, you play with the View specifically ActionMenuView so try this, copy the codes into your Activity
//we declare our objects globally
Toolbar tool; ActionMenuView amv;
then override onPrepareOptionsMenu, what you decide to return is your choice
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
//to be safe you can check if children are greater than 1
amv = (ActionMenuView) tool.getChildAt(1);//hope you've met amv
return true;
}
now this is the crucial part- whenever you want to animate the "3 verticall dots" -(your overflow) you have to check visible children-(i.e if you want to) actually forget that
amv.getChildAt(amv.getChildCount()-1).startAnimation(AnimationUtils.loadAnimation(
MainActivity.this,R.anim.abc_fade_in));
that gives you a basic fade-in animation- you can pimp your ride now.
EDIT 1:
The above code made assumptions that you have nothing added to your Toolbar aside from just inflating the menu in onCreateOptionsMenu.
Suppose you have a complex ToolBar use this rather for your initialisation
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
for(int i =0; i < tool.getChildCount(); ++i){
if(tool.getChildAt(i).getClass().getSimpleName().equals("ActionMenuView")){
amv = (ActionMenuView) tool.getChildAt(i);
break;
}
}
return true;
}
Also where you call your initialisation of amv View can be in either onCreateOptionsMenu or onPrepareOptionsMenu, i chose onPrepareOptionsMenu because i wanted readability
Hope it helps