I have implemented BottomNavigationView in my app. Everything going easy and perfect but there is one problem i.e. on back press I want to get the currently active tab selected but now selected tab does not change when back press. Fragment changes but tab selection does not change. How can I detect the current tab and change the selected tab on back press. I tried a lot of things to do but not able to get selected tab ID.Please help.
Code:
int i = getSelectedItem(bottomNavigationView);
Log.e("TAG", "onCreate:tab "+i );
private int getSelectedItem(BottomNavigationView bottomNavigationView){
Menu menu = bottomNavigationView.getMenu();
for (int i=0;i<bottomNavigationView.getMenu().size();i++){
MenuItem menuItem = menu.getItem(i);
if (menuItem.isChecked()){
return menuItem.getItemId();
}
}
return 0;
}
If you want to find the checked item id, try this:
int checkedItemId = bottomNavigationView.getSelectedItemId();
To change current selected item, use this:
bottomNavigationView.getMenu().findItem(R.id.target_item_nemu).setChecked(true);
Related
I have 4 tabs in my app. In which one is accessible without log-in but others can't be. So, I need to implement a functionality in which if a user clicks on that tab then rest 4 will be disabled and when I click on those tabs I only want toast but if I click on those tabs I get toast but it also got selected but fragment not changed. I want to disable that tab
I have assigned a value to a variable to check whether it is without logging or after logging.
Code:
case R.id.home:
if(value.equals("1")){
Toast.makeText(CarerSeekerActivity.this,R.string.login_signup,Toast.LENGTH_SHORT).show();
navigation.getMenu().getItem(0).setEnabled(false);
}
else {
fragment = new CreatePersonalizedPackageCareSeekerFragment();
changeFragments(fragment);
}
return true;
but it is showing toast and but selected that tab. I do not want to make it selected. Please help.
After setting the menu please write below code in your on create method:
if(isloggedin){
// do click action which is required if the user already logged in
change your fragment from here
}else{
bottomnavigation.getMenu().getItem(your_position).setEnabled(false); // disable menu if user not logged in
Toast.makeText(CarerSeekerActivity.this,R.string.login_signup,Toast.LENGTH_SHORT).show();
}
I know I'm replying 3 years later, but this is the function I've done for changing all the tabs to clickable or not clickable. You can easily adapt it for what you asked.
private void setNavigationBarClickableItems(BottomNavigationBar bottomNavigationBar, boolean clickable) {
BottomNavigationMenuView menuView = (BottomNavigationMenuView) bottomNavigationBar.getChildAt(0);
for (int i = 0; i < menuView.getChildCount(); i++) {
menuView.getChildAt(i).setClickable(clickable);
}
}
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Data data = mListDatas.get(i);
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ThirdFragment thirdFragment = new ThirdFragment();
Bundle bundle = new Bundle();
bundle.putSerializable("detail", data);
thirdFragment.setArguments(bundle);
transaction.replace(R.id.content,ThirdFragment).addToBackStack(null).commit();
BottomNavigationView navigation = (BottomNavigationView)view.findViewById(R.id.navigation_bottomview);
navigation.setSelectedItemId(R.id.navigation_third_tab);
}
});
In the above code i need to open a new fragment on the bottom tab from a list item click,
i am able to open a new fragment but the current tab remains unchanged i.e, after redirecting to the third fragment on third bottom tab ,the current tab i.e, Second Tab is active.
How can i change the active state of bottom tab from second tab to third tab on the list item click ??
Your activity needs to implement the BottomNavigationView.OnNavigationItemSelectedListener. This can be done simply by adding implements BottomNavigationView.OnNavigationItemSelectedListener after your class name, this is done so you can get the click callback whenever one of the bottom menu items are clicked on.
Then you need to override the onNavigationItemSelected function so add the following code to your activity.
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.tab_1:
handleFragmentChange(Fragment_1.newInstance());
return true;
}
return false;
}
Also add navigation.setOnNavigationItemSelectedListener(this); in the same activity once you have found the view using findViewById. This is done so that the system knows that your class is handling the event when a bottom menu is clicked so it calls the above function in your class.
The return true is what notifies the android system that it needs to switch the tab.
if this code locates in fragment then you need to replace
BottomNavigationView navigation = view.findViewById(R.id.navigation_bottomview);
navigation.setSelectedItemId(R.id.navigation_third_tab);
before
...commit();
and add getRootView() because your BottomNavigationView locate inside main container - root activity
BottomNavigationView navigation = view.getRootView().findViewById(R.id.navigation_bottomview);
navigation.setSelectedItemId(R.id.navigation_third_tab);
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";
}
}
When transitioning between pages, each fragment page shares the same menu options. The menu option contains button which launches an activity. That activity is highly dependent on the information the current page item shows.
I noticed that when I change the view such that, the next page is almost shown on the screen (not fully transitioned) and I select the option for that item, the options shows the data from the previous item. I think this is because, he transition between pages was not fully complete. This is kind of confusing for my users. There could be people who swipe faster and press the option button. I noticed then when swiping between fragments and then suddenly press the menu option. The options shows the data from the previously active page.
If I could only hide the menu options, and only show it when the page is fully transitioned, I believe I can solve this problem. Or else, maybe I am doing something wrong which could have averted this in the first place?
I am using FragmentStatePagerAdapter.
Thank you!
Use ViewPager.SimpleOnPageChangeListener and when the onPageScrollStateChanged event is triggered check to see the state of the scroll if is idle then the page is in view and active (allow user to press the menu button), if is in another state then lock/hide the menu buttons.
I think I was able to solve my problem. I created an interface on my fragment which the hosting activity has to implement:
public interface OnOptionsMenuEnabledListener{ public boolean onOptionsMenuEnabledListener(); }
The hosting activity will just return a flag indicating if the menu is enabled.
#Override
public boolean onOptionsMenuEnabledListener()
{
return mOptionsEnabled;
}
And set the flag via ViewPager.onPageScrollStateChanged (int state):
#Override
public void onPageScrollStateChanged(int state)
{
switch(state)
{
case ViewPager.SCROLL_STATE_IDLE:
mOptionsEnabled = true;
break;
case ViewPager.SCROLL_STATE_DRAGGING:
mOptionsEnabled = false;
break;
case ViewPager.SCROLL_STATE_SETTLING:
mOptionsEnabled = true;
break;
}
}
Every time the option is being selected during screen transition, I call the interface method to communicate to me what the status of the flag:
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
boolean enable = true;
if(mOnOptionsMenuEnabledListener != null)
{
enable = mOnOptionsMenuEnabledListener.onOptionsMenuEnabledListener();
}
if(enable)
{
...
// select your menu items
}
return true;
}
So in this approach, the menu is still there (which is a big plus). But the option menu doesn't react until it settles down on a particular page.
With this I no longer encounter the problem.
I hope this help someone in the future!
Cheers!
When the button is clicked check ViewPagers current item -
https://developer.android.com/reference/android/support/v4/view/ViewPager.html#getCurrentItem()
YourObject object = yourList.get(yourViewPager.getCurrentItem());
I've been trying to get my actionbar buttons to show on click but can't get it to work. I got 2 buttons and if i click on one i want the other to show and the other to get invinsible.
Here is my code:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
MenuItem brandsMenu = (MenuItem)findViewById(R.id.action_brands);
MenuItem categoryMenu = (MenuItem)findViewById(R.id.action_category);
switch (item.getItemId()) {
case R.id.action_category:
brandsMenu.setVisible(true);
return true;
case R.id.action_brands:
categoryMenu.setVisible(true);
}
This only shows errors. Any Suggestions?
You need to call InvalidateOptionsMenu when you want to make changes to your menu.
You then use the onCreateOptionsMenu override to apply those changes.
Define MenuItems named brandsMenu and categoryMenu and initialize them onPrepareOptionsMenu
categoryMenu = menu.findItem(R.id.action_category);
brandsMenu = menu.findItem(R.id.action_brands);
You should be able to change visibility such as categoryMenu.setVisible(true);
You can't set visibility on menuitems.
You should invalidate the options menu and add only the menuItems you want to be visible