I'm trying to start a fragment from the toolbar (the toolbar is in a fragment too) but it's not starting, that was not the case when it was in the main activity it was working fine.
If You Want More Reference of any file or want to see other files
please tell me I will upload it
Java Files
Home_Fragment.java
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_home, container, false);
MaterialToolbar materialToolbar = view.findViewById(R.id.tool_bar);
materialToolbar.setOnMenuItemClickListener(toolbarItemClickListener);
return view;
}
private final MaterialToolbar.OnMenuItemClickListener toolbarItemClickListener =
(MenuItem item) -> {
Fragment selectedFragment = null;
if (item.getItemId() == R.id.search_button) {
selectedFragment = new Search_Fragment();
}
return true;
};
XML Files
tool_bar.xml(menu XML)
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/search_button"
android:icon="#drawable/ic_baseline_search_24"
android:title=""
app:showAsAction="always"
android:iconTint="#color/white"/>
</menu>
tool_bar.xml
<com.google.android.material.appbar.MaterialToolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/tool_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="#color/black"
app:itemIconSize="29dp"
app:layout_scrollFlags="scroll|enterAlways"
app:menu="#menu/tool_bar">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="#string/app"
android:textColor="#color/white"
android:textSize="23sp"
android:textStyle="bold" />
</com.google.android.material.appbar.MaterialToolbar>
You've just created a new instance of your Fragment, but didn't add it to the FragmentManager, so it didn't start. You have to make a FragmentTransaction to start the fragment.
Fragment selectedFragment = null;
if (item.getItemId() == R.id.search_button) {
selectedFragment = new Search_Fragment();
getParentFragmentManager.beginTransaction()
.replace(R.id.fragment_container, Search_Fragment.class, null) // fragment_container is the ID of the fragment holder
.setReorderingAllowed(true)
.commit();
}
I used BottomNavigationbar in my android app. When I run on a tablet, it shows very small icons in bottomnavigationbar. I want to increase the size for tablets.
I tried to put different sizes of icons in drawable folders but the problem is still there.
main_activity.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/backgroundGray"
tools:context="com.shakeel.board.MainActivity">
<FrameLayout
android:id="#+id/fragments_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/bottom_nav_bar">
</FrameLayout>
<android.support.design.widget.BottomNavigationView
android:id="#+id/bottom_nav_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:menu="#menu/bottom_navigation_menu"
android:padding="5dp"
android:background="#color/white">
</android.support.design.widget.BottomNavigationView>
bottom_navigation_menu.xml
<item android:id="#+id/nav_home"
android:title="Home"
android:icon="#drawable/home"/>
<item android:id="#+id/nav_favorites"
android:title="Favorite"
android:icon="#drawable/ic_favorite_red_24dp"/>
<item android:id="#+id/nav_shop"
android:title="Shop"
android:icon="#drawable/ic_shopping_basket_black_24dp"/>
<item android:id="#+id/nav_setting"
android:title="Setting"
android:icon="#drawable/ic_settings_black_24dp"/>
MainActivity.class
public class MainActivity extends AppCompatActivity {
BottomNavigationView bootomNavigation;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bootomNavigation = findViewById(R.id.bottom_nav_bar);
BottomNavigationViewHelper.removeShiftMode(bootomNavigation);
getSupportFragmentManager().beginTransaction().replace(R.id.fragments_container, new HomeFragment()).commit();
bootomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Fragment selectedFragment = null;
switch (item.getItemId()){
case R.id.nav_home:
selectedFragment = new HomeFragment();
break;
case R.id.nav_favorites:
selectedFragment = new FavoritesFragment();
break;
case R.id.nav_shop:
selectedFragment = new ShopFragment();
break;
case R.id.nav_setting:
selectedFragment = new SettingFragment();
break;
}
getSupportFragmentManager().beginTransaction().replace(R.id.fragments_container, selectedFragment).commit();
return true;
}
});
}
}
You can download your icons from the material design page, select your icons and then select the Android option (see image below) and you will get a set of the same icon in different sizes for different screen sizes.
I have made an app with bottom navigation view with Promo, Store, Reward, Coupon and Account tabs when I am changing from Coupon fragment to any other fragment, the bottom navigation view gets shrunk down as shown in the image, I tried changing layout width, height and converting coordinator layout to linear layout but it didn't help. The problem is occurring when I'm switching from home to any other tab only.
Layout File activity_main.xml
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.MainActivity">
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="56dp"
android:text="#string/title_home"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<android.support.design.widget.BottomNavigationView
android:id="#+id/navigation"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="0dp"
android:layout_marginStart="0dp"
android:background="#color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:itemTextColor="#color/selector_bottom_navigation"
app:itemIconTint="#color/selector_bottom_navigation"
app:menu="#menu/navigation" />
Java File MainActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//loading the default fragment
loadFragment(new PromoFragment());
//getting bottom navigation view and attaching the listener
BottomNavigationView navigation = findViewById(R.id.navigation);
BottomNavigationViewUtils.disableShiftMode(navigation);
navigation.setOnNavigationItemSelectedListener(this);
}
#Override
public boolean onCreatePanelMenu(int featureId, Menu menu) {
getMenuInflater().inflate(R.menu.menu_wallet, menu);
return super.onCreatePanelMenu(featureId, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.menu_wallet1:
return true;
case R.id.menu_qrcode:
Intent intent = new Intent(this, ScannerActivity.class);
startActivity(intent);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Fragment fragment = null;
switch (item.getItemId()) {
case R.id.navigation_promo:
fragment = new PromoFragment();
break;
case R.id.navigation_store:
fragment = new StoreFragment();
break;
case R.id.navigation_reward:
fragment = new RewardFragment();
break;
case R.id.navigation_coupon:
fragment = new CouponFragment();
break;
case R.id.navigation_account:
fragment = new AccountFragment();
break;
}
return loadFragment(fragment);
}
private boolean loadFragment(Fragment fragment) {
if (fragment != null) {
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, fragment)
.commit();
return true;
}
return false;
}
This is the picture I meant:
I previously added SearchView to the coupon fragment and fragment store
It turns out that if you are using a coordinator layout and viewpager inside a fragment, you will notice that the viewpager extends the screen a bit. Just disable the scroll features of the coordinator layout inside the fragment and you will notice the bottom bar doesn't get shrunk. Weird I know, but it works.
I add android:fitsSystemWindows="false" in CoordinatorLayout and it worked
Find android:fitsSystemWindows="true" in your fragment xml and remove this line
or change it to android:fitsSystemWindows="false". Your problem will be solved.
I have a Bottom Navigation View with 4 items.
I wish to set the items in the middle of each bottom navigation view button and I have found a method but it works only when the application starts.
After I select another item, every icon moves up and I don't know why they are not keeping their position.
public class MainActivity extends AppCompatActivity{
private Toolbar mToolbar;
private BottomNavigationView bottomNavigationView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mToolbar = (Toolbar) findViewById(R.id.customToolbar);
setSupportActionBar(mToolbar);
setTitle("");
mToolbar.setNavigationIcon(R.mipmap.back_icon);
bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottom_navigation);
BottomNavigationViewShiftDisable.disableShiftMode(bottomNavigationView);
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Fragment fragment = null;
switch (item.getItemId()) {
case R.id.profile:
fragment = new FirstFragment();
break;
case R.id.friends:
fragment = new SecondFragment();
break;
case R.id.circle:
fragment = new ThirdFragment();
break;
case R.id.settings:
fragment = new ForthFragment();
break;
}
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame_layout, fragment);
transaction.commit();
setMenuIconsInMiddle(bottomNavigationView);
return true;
}
});
bottomNavigationView.setSelectedItemId(R.id.profile);
}
/**
* This method is used to set margins for all the icons in the menu that is used in the
* bottom navigation view.
* #param navigationView an instance of the Bottom navigation view that holds the menu with
* the icons.
*/
public void setMenuIconsInMiddle(BottomNavigationView navigationView){
BottomNavigationMenuView menuView = (BottomNavigationMenuView)navigationView.getChildAt(0);
for(int index = 0; index <menuView.getChildCount(); index++){
final View iconView = menuView.getChildAt(index).findViewById(android.support.design.R.id.icon);
final ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams)iconView.getLayoutParams();
layoutParams.setMargins(0,50,0,0);
navigationView.requestLayout();
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.hermes.profilescreen.MainActivity">
<include layout="#layout/custom_toolbar"/>
<include layout="#layout/bottom_navigation"/>
</RelativeLayout>
bottom_nav_main.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
>
<item
android:id="#+id/profile"
android:enabled="true"
android:icon="#drawable/ic_people_outline_black_24dp"
app:showAsAction="ifRoom"
android:title=""
/>
<item
android:id="#+id/friends"
android:enabled="true"
android:icon="#drawable/ic_person_black_24dp"
app:showAsAction="ifRoom"
android:title=""
/>
<item
android:id="#+id/circle"
android:enabled="true"
android:icon="#drawable/ic_panorama_fish_eye_black_24dp"
app:showAsAction="ifRoom"
android:title=""
/>
<item
android:id="#+id/settings"
android:enabled="true"
android:icon="#drawable/setting_white"
app:showAsAction="ifRoom"
android:title=""
/>
</menu>
bottom_navigation.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/frame_layout"
android:layout_above="#+id/bottom_navigation"
>
</FrameLayout>
<android.support.design.widget.BottomNavigationView
android:id="#+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#color/light_black"
app:itemBackground="#drawable/set_backgorund"
app:itemIconTint="#color/item_state"
app:menu="#menu/bottom_nav_main"
/>
</RelativeLayout>
call setMenuIconsInMiddle on a thread. try this:-
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
//your code here
...
...
...
//Looper.getMainLooper() runs on main thread
new Handler(Looper.getMainLooper()).post(new Runnable(){
#Override
public void run() {
setMenuIconsInMiddle(bottomNavigationView);
}
});
return true;
}
});
this is working for me...
Saw the new guideline came out, and used in google photos latest app.
Have no idea how to use the new Bottom Navigation Bar.
See through the new support lib, didn't find any lead.
Can not find any official sample.
How to use the new Bottom bar? Don't want to do any customize.
I think you might looking for this.
Here's a quick snippet to get started:
public class MainActivity extends AppCompatActivity {
private BottomBar mBottomBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Notice how you don't use the setContentView method here! Just
// pass your layout to bottom bar, it will be taken care of.
// Everything will be just like you're used to.
mBottomBar = BottomBar.bind(this, R.layout.activity_main,
savedInstanceState);
mBottomBar.setItems(
new BottomBarTab(R.drawable.ic_recents, "Recents"),
new BottomBarTab(R.drawable.ic_favorites, "Favorites"),
new BottomBarTab(R.drawable.ic_nearby, "Nearby"),
new BottomBarTab(R.drawable.ic_friends, "Friends")
);
mBottomBar.setOnItemSelectedListener(new OnTabSelectedListener() {
#Override
public void onItemSelected(final int position) {
// the user selected a new tab
}
});
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mBottomBar.onSaveInstanceState(outState);
}
}
Here is reference link.
https://github.com/roughike/BottomBar
EDIT New Releases.
The Bottom Navigation View has been in the material design guidelines for some time, but it hasn’t been easy for us to implement it into our apps. Some applications have built their own solutions, whilst others have relied on third-party open-source libraries to get the job done. Now the design support library is seeing the addition of this bottom navigation bar, let’s take a dive into how we can use it!
How to use ?
To begin with we need to update our dependency!
compile ‘com.android.support:design:25.0.0’
Design xml.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Content Container -->
<android.support.design.widget.BottomNavigationView
android:id="#+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:itemBackground="#color/colorPrimary"
app:itemIconTint="#color/white"
app:itemTextColor="#color/white"
app:menu="#menu/bottom_navigation_main" />
</RelativeLayout>
Create menu as per your requirement.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/action_favorites"
android:enabled="true"
android:icon="#drawable/ic_favorite_white_24dp"
android:title="#string/text_favorites"
app:showAsAction="ifRoom" />
<item
android:id="#+id/action_schedules"
android:enabled="true"
android:icon="#drawable/ic_access_time_white_24dp"
android:title="#string/text_schedules"
app:showAsAction="ifRoom" />
<item
android:id="#+id/action_music"
android:enabled="true"
android:icon="#drawable/ic_audiotrack_white_24dp"
android:title="#string/text_music"
app:showAsAction="ifRoom" />
</menu>
Handling Enabled / Disabled states. Make selector file.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_checked="true"
android:color="#color/colorPrimary" />
<item
android:state_checked="false"
android:color="#color/grey" />
</selector>
Handle click events.
BottomNavigationView bottomNavigationView = (BottomNavigationView)
findViewById(R.id.bottom_navigation);
bottomNavigationView.setOnNavigationItemSelectedListener(
new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.action_favorites:
break;
case R.id.action_schedules:
break;
case R.id.action_music:
break;
}
return false;
}
});
Edit : Using Androidx you just need to add below dependencies.
implementation 'com.google.android.material:material:1.2.0-alpha01'
Layout
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:layout_gravity="bottom"
app:menu="#menu/bottom_navigation_menu"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</FrameLayout>
If you want to read more about it's methods and how it works read this.
Surely it will help you.
You should use BottomNavigationView from v25 Android Support Library.
It represents a standard bottom navigation bar for application.
Here is a post on Medium that has a step by step guide:
https://medium.com/#hitherejoe/exploring-the-android-design-support-library-bottom-navigation-drawer-548de699e8e0#.9vmiekxze
My original answer dealt with the BottomNavigationView, but now there is a BottomAppBar. I added a section at the top for that with an implementation link.
Bottom App Bar
The BottomAppBar supports a Floating Action Button.
Image from here. See the documentation and this tutorial for help setting up the BottomAppBar.
Bottom Navigation View
The following full example shows how to make a Bottom Navigation View similar to the image in the question. See also Bottom Navigation in the documentation.
Add the design support library
Add this line to your app's build.grade file next to the other support library things.
implementation 'com.android.support:design:28.0.0'
Replace the version number with whatever is current.
Create the Activity layout
The only special thing we have added to the layout is the BottomNavigationView. To change the color of the icon and text when it is clicked, you can use a selector instead of specifying the color directly. This is omitted for simplicity here.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.BottomNavigationView
android:id="#+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:menu="#menu/bottom_nav_menu"
app:itemBackground="#color/colorPrimary"
app:itemIconTint="#android:color/white"
app:itemTextColor="#android:color/white" />
</RelativeLayout>
Notice that we used layout_alignParentBottom to actually put it at the bottom.
Define the menu items
The xml above for Bottom Navigation View referred to bottom_nav_menu. This is what defines each item in our view. We will make it now. All you have to do is add a menu resource just like you would for an Action Bar or Toolbar.
bottom_nav_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/action_recents"
android:enabled="true"
android:icon="#drawable/ic_action_recents"
android:title="Recents"
app:showAsAction="ifRoom" />
<item
android:id="#+id/action_favorites"
android:enabled="true"
android:icon="#drawable/ic_action_favorites"
android:title="Favorites"
app:showAsAction="ifRoom" />
<item
android:id="#+id/action_nearby"
android:enabled="true"
android:icon="#drawable/ic_action_nearby"
android:title="Nearby"
app:showAsAction="ifRoom" />
</menu>
You will need to add the appropriate icons to your project. This is not very difficult if you go to File > New > Image Asset and choose Action Bar and Tab Icons as the Icon Type.
Add an item selected listener
There is nothing special happening here. We just add a listener to the Bottom Navigation Bar in our Activity's onCreate method.
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BottomNavigationView bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottom_navigation);
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.action_recents:
Toast.makeText(MainActivity.this, "Recents", Toast.LENGTH_SHORT).show();
break;
case R.id.action_favorites:
Toast.makeText(MainActivity.this, "Favorites", Toast.LENGTH_SHORT).show();
break;
case R.id.action_nearby:
Toast.makeText(MainActivity.this, "Nearby", Toast.LENGTH_SHORT).show();
break;
}
return true;
}
});
}
}
Need more help?
I learned how to do this watching the following YouTube video. The computer voice is a little strange, but the demonstration is very clear.
Android Studio Tutorial - Bottom Navigation View
You can also use Tab Layout with custom tab view to achieve this.
custom_tab.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:gravity="center"
android:orientation="vertical"
android:paddingBottom="10dp"
android:paddingTop="8dp">
<ImageView
android:id="#+id/icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:scaleType="centerInside"
android:src="#drawable/ic_recents_selector" />
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:textAllCaps="false"
android:textColor="#color/tab_color"
android:textSize="12sp"/>
</LinearLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v4.view.ViewPager
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
style="#style/AppTabLayout"
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="?attr/colorPrimary" />
</LinearLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
private TabLayout mTabLayout;
private int[] mTabsIcons = {
R.drawable.ic_recents_selector,
R.drawable.ic_favorite_selector,
R.drawable.ic_place_selector};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Setup the viewPager
ViewPager viewPager = (ViewPager) findViewById(R.id.view_pager);
MyPagerAdapter pagerAdapter = new MyPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(pagerAdapter);
mTabLayout = (TabLayout) findViewById(R.id.tab_layout);
mTabLayout.setupWithViewPager(viewPager);
for (int i = 0; i < mTabLayout.getTabCount(); i++) {
TabLayout.Tab tab = mTabLayout.getTabAt(i);
tab.setCustomView(pagerAdapter.getTabView(i));
}
mTabLayout.getTabAt(0).getCustomView().setSelected(true);
}
private class MyPagerAdapter extends FragmentPagerAdapter {
public final int PAGE_COUNT = 3;
private final String[] mTabsTitle = {"Recents", "Favorites", "Nearby"};
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
public View getTabView(int position) {
// Given you have a custom layout in `res/layout/custom_tab.xml` with a TextView and ImageView
View view = LayoutInflater.from(MainActivity.this).inflate(R.layout.custom_tab, null);
TextView title = (TextView) view.findViewById(R.id.title);
title.setText(mTabsTitle[position]);
ImageView icon = (ImageView) view.findViewById(R.id.icon);
icon.setImageResource(mTabsIcons[position]);
return view;
}
#Override
public Fragment getItem(int pos) {
switch (pos) {
case 0:
return PageFragment.newInstance(1);
case 1:
return PageFragment.newInstance(2);
case 2:
return PageFragment.newInstance(3);
}
return null;
}
#Override
public int getCount() {
return PAGE_COUNT;
}
#Override
public CharSequence getPageTitle(int position) {
return mTabsTitle[position];
}
}
}
Download Complete Sample Project
Google has launched the BottomNavigationView after the version 25.0.0 of the design support library. But it came with the following limitations:
You can't remove titles and center icon.
You cant't change titles text size.
Y̶o̶u̶ ̶c̶a̶n̶'̶t̶ ̶c̶h̶a̶n̶g̶e̶ ̶t̶h̶e̶ ̶b̶a̶c̶k̶g̶r̶o̶u̶n̶d̶ ̶c̶o̶l̶o̶r̶ ̶i̶t̶ ̶i̶s̶ ̶a̶l̶w̶a̶y̶s̶ ̶t̶h̶e̶ ̶c̶o̶l̶o̶r̶P̶r̶i̶m̶a̶r̶y̶.̶
It doesn't have a BottomNavigationBehavior: so no integration with FAB or SnackBar through CordinatorLayout.
Every menuItem is a pure extension of FrameLayout so it doesn't have any nice circle reveal effect
So the max you can do with this fist version of BottomNavigationView is: (without any reflection or implementing the lib by yourself).
So, If you want any of these. You can use a third part library like roughike/BottomBar or implement the lib by yourself.
As Sanf0rd mentioned, Google launched the BottomNavigationView as part of the Design Support Library version 25.0.0. The limitations he mentioned are mostly true, except that you CAN change the background color of the view and even the text color and icon tint color. It also has an animation when you add more than 4 items (sadly it cannot be enabled or disabled manually).
I wrote a detailed tutorial about it with examples and an accompanying repository, which you can read here:
https://blog.autsoft.hu/now-you-can-use-the-bottom-navigation-view-in-the-design-support-library/
The gist of it
You have to add these in your app level build.gradle:
compile 'com.android.support:appcompat-v7:25.0.0'
compile 'com.android.support:design:25.0.0'
You can include it in your layout like this:
<android.support.design.widget.BottomNavigationView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/bottom_navigation_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:itemBackground="#color/darkGrey"
app:itemIconTint="#color/bottom_navigation_item_background_colors"
app:itemTextColor="#color/bottom_navigation_item_background_colors"
app:menu="#menu/menu_bottom_navigation" />
You can specify the items via a menu resource like this:
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/action_one"
android:icon="#android:drawable/ic_dialog_map"
android:title="One"/>
<item
android:id="#+id/action_two"
android:icon="#android:drawable/ic_dialog_info"
android:title="Two"/>
<item
android:id="#+id/action_three"
android:icon="#android:drawable/ic_dialog_email"
android:title="Three"/>
<item
android:id="#+id/action_four"
android:icon="#android:drawable/ic_popup_reminder"
android:title="Four"/>
</menu>
And you can set the tint and text color as a color list, so the currently selected item is highlighted:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:color="#color/colorAccent"
android:state_checked="false"/>
<item
android:color="#android:color/white"
android:state_checked="true"/>
</selector>
Finally, you can handle the selection of the items with an OnNavigationItemSelectedListener:
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Fragment fragment = null;
switch (item.getItemId()) {
case R.id.action_one:
// Switch to page one
break;
case R.id.action_two:
// Switch to page two
break;
case R.id.action_three:
// Switch to page three
break;
}
return true;
}
});
Other alternate library you can try :- https://github.com/Ashok-Varma/BottomNavigation
<com.ashokvarma.bottomnavigation.BottomNavigationBar
android:layout_gravity="bottom"
android:id="#+id/bottom_navigation_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
BottomNavigationBar bottomNavigationBar = (BottomNavigationBar) findViewById(R.id.bottom_navigation_bar);
bottomNavigationBar
.addItem(new BottomNavigationItem(R.drawable.ic_home_white_24dp, "Home"))
.addItem(new BottomNavigationItem(R.drawable.ic_book_white_24dp, "Books"))
.addItem(new BottomNavigationItem(R.drawable.ic_music_note_white_24dp, "Music"))
.addItem(new BottomNavigationItem(R.drawable.ic_tv_white_24dp, "Movies & TV"))
.addItem(new BottomNavigationItem(R.drawable.ic_videogame_asset_white_24dp, "Games"))
.initialise();
i've made a private class which uses a gridview and a menu resource:
private class BottomBar {
private GridView mGridView;
private Menu mMenu;
private BottomBarAdapter mBottomBarAdapter;
private View.OnClickListener mOnClickListener;
public BottomBar (#IdRes int gridviewId, #MenuRes int menuRes,View.OnClickListener onClickListener) {
this.mGridView = (GridView) findViewById(gridviewId);
this.mMenu = getMenu(menuRes);
this.mOnClickListener = onClickListener;
this.mBottomBarAdapter = new BottomBarAdapter();
this.mGridView.setAdapter(mBottomBarAdapter);
}
private Menu getMenu(#MenuRes int menuId) {
PopupMenu p = new PopupMenu(MainActivity.this,null);
Menu menu = p.getMenu();
getMenuInflater().inflate(menuId,menu);
return menu;
}
public GridView getGridView(){
return mGridView;
}
public void show() {
mGridView.setVisibility(View.VISIBLE);
mGridView.animate().translationY(0);
}
public void hide() {
mGridView.animate().translationY(mGridView.getHeight());
}
private class BottomBarAdapter extends BaseAdapter {
private LayoutInflater mInflater;
public BottomBarAdapter(){
this.mInflater = LayoutInflater.from(MainActivity.this);
}
#Override
public int getCount() {
return mMenu.size();
}
#Override
public Object getItem(int i) {
return mMenu.getItem(i);
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
MenuItem item = (MenuItem) getItem(i);
if (view==null){
view = mInflater.inflate(R.layout.your_item_layout,null);
view.setId(item.getItemId());
}
view.setOnClickListener(mOnClickListener);
view.findViewById(R.id.bottomnav_icon).setBackground(item.getIcon());
((TextView) view.findViewById(R.id.bottomnav_label)).setText(item.getTitle());
return view;
}
}
your_menu.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/item1_id"
android:icon="#drawable/ic_item1"
android:title="#string/title_item1"/>
<item android:id="#+id/item2_id"
android:icon="#drawable/ic_item2"
android:title="#string/title_item2"/>
...
</menu>
and a custom layout item your_item_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_margin="16dp">
<ImageButton android:id="#+id/bottomnav_icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="top|center_horizontal"
android:layout_marginTop="8dp"
android:layout_marginBottom="4dp"/>
<TextView android:id="#+id/bottomnav_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:layout_marginBottom="8dp"
android:layout_marginTop="4dp"
style="#style/mystyle_label" />
</LinearLayout>
usage inside your mainactivity:
BottomBar bottomBar = new BottomBar(R.id.YourGridView,R.menu.your_menu, mOnClickListener);
and
private View.OnClickListener mOnClickListener = new View.OnClickListener() {
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.item1_id:
//todo item1
break;
case R.id.item2_id:
//todo item2
break;
...
}
}
}
and in layout_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
...
<FrameLayout android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
<GridView android:id="#+id/bottomNav"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/your_background_color"
android:verticalSpacing="0dp"
android:horizontalSpacing="0dp"
android:numColumns="4"
android:stretchMode="columnWidth"
app:layout_anchor="#id/fragment_container"
app:layout_anchorGravity="bottom"/>
</android.support.design.widget.CoordinatorLayout>
I think this is also be useful.
Snippet
public class MainActivity : AppCompatActivity, BottomNavigationBar.Listeners.IOnTabSelectedListener
{
private BottomBar _bottomBar;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.MainActivity);
_bottomBar = BottomBar.Attach(this, bundle);
_bottomBar.SetItems(
new BottomBarTab(Resource.Drawable.ic_recents, "Recents"),
new BottomBarTab(Resource.Drawable.ic_favorites, "Favorites"),
new BottomBarTab(Resource.Drawable.ic_nearby, "Nearby")
);
_bottomBar.SetOnItemSelectedListener(this);
_bottomBar.HideShadow();
_bottomBar.UseDarkTheme(true);
_bottomBar.SetTypeFace("Roboto-Regular.ttf");
var badge = _bottomBar.MakeBadgeForTabAt(1, Color.ParseColor("#f02d4c"), 1);
badge.AutoShowAfterUnSelection = true;
}
public void OnItemSelected(int position)
{
}
protected override void OnSaveInstanceState(Bundle outState)
{
base.OnSaveInstanceState(outState);
// Necessary to restore the BottomBar's state, otherwise we would
// lose the current tab on orientation change.
_bottomBar.OnSaveInstanceState(outState);
}
}
Links
https://github.com/pocheshire/BottomNavigationBar
It's https://github.com/roughike/BottomBar ported to C# for Xamarin developers
There is a new official BottomNavigationView in version 25 of the Design Support Library
https://developer.android.com/reference/android/support/design/widget/BottomNavigationView.html
add in gradle
compile 'com.android.support:design:25.0.0'
XML
<android.support.design.widget.BottomNavigationView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:design="http://schema.android.com/apk/res/android.support.design"
android:id="#+id/navigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
design:menu="#menu/my_navigation_items" />
This library, BottomNavigationViewEx, extends Google's BottomNavigationView. You can easily customise Google's library to have bottom navigation bar the way you want it to be. You can disable the shifting mode, change visibility of the icons and texts and so much more. Definitely try it out.
I have referred this github post and I have set the three layouts for three fragment pages in bottom tab bar.
FourButtonsActivity.java:
bottomBar.setFragmentItems(getSupportFragmentManager(), R.id.fragmentContainer,
new BottomBarFragment(LibraryFragment.newInstance(R.layout.library_fragment_layout), R.drawable.ic_update_white_24dp, "Recents"),
new BottomBarFragment(PhotoEffectFragment.newInstance(R.layout.photo_effect_fragment), R.drawable.ic_local_dining_white_24dp, "Food"),
new BottomBarFragment(VideoFragment.newInstance(R.layout.video_layout), R.drawable.ic_favorite_white_24dp, "Favorites")
);
To set the badge count :
BottomBarBadge unreadMessages = bottomBar.makeBadgeForTabAt(1, "#E91E63", 4);
unreadMessages.show();
unreadMessages.setCount(4);
unreadMessages.setAnimationDuration(200);
unreadMessages.setAutoShowAfterUnSelection(true);
LibraryFragment.java:
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class LibraryFragment extends Fragment {
private static final String STARTING_TEXT = "Four Buttons Bottom Navigation";
public LibraryFragment() {
}
public static LibraryFragment newInstance(int resource) {
Bundle args = new Bundle();
args.putInt(STARTING_TEXT, resource);
LibraryFragment sampleFragment = new LibraryFragment();
sampleFragment.setArguments(args);
return sampleFragment;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = LayoutInflater.from(getActivity()).inflate(
getArguments().getInt(STARTING_TEXT), null);
return view;
}
<android.support.design.widget.BottomNavigationView
android:id="#+id/navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="?android:attr/windowBackground"
app:menu="#menu/navigation" />
navigation.xml(inside menu)
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/navigation_home"
android:icon="#drawable/ic_home_black_24dp"
android:title="#string/title_home"
app:showAsAction="always|withText"
android:enabled="true"/>
Inside onCreate() method,
BottomNavigationView navigation = (BottomNavigationView)findViewById(R.id.navigation);
//Dont forgot this line
BottomNavigationViewHelper.disableShiftMode(navigation);
And Create class as below.
public class BottomNavigationViewHelper {
public static void disableShiftMode(BottomNavigationView view) {
BottomNavigationMenuView menuView = (BottomNavigationMenuView) view.getChildAt(0);
try {
Field shiftingMode = menuView.getClass().getDeclaredField("mShiftingMode");
shiftingMode.setAccessible(true);
shiftingMode.setBoolean(menuView, false);
shiftingMode.setAccessible(false);
for (int i = 0; i < menuView.getChildCount(); i++) {
BottomNavigationItemView item = (BottomNavigationItemView) menuView.getChildAt(i);
//noinspection RestrictedApi
item.setShiftingMode(false);
// set once again checked value, so view will be updated
//noinspection RestrictedApi
item.setChecked(item.getItemData().isChecked());
}
} catch (NoSuchFieldException e) {
Log.e("BNVHelper", "Unable to get shift mode field", e);
} catch (IllegalAccessException e) {
Log.e("BNVHelper", "Unable to change value of shift mode", e);
}
}
}
You can create the layouts according to the above-mentioned answers
If anyone wants to use this in kotlin:-
private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item ->
when (item.itemId) {
R.id.images -> {
// do your work....
return#OnNavigationItemSelectedListener true
}
R.id.videos ->
{
// do your work....
return#OnNavigationItemSelectedListener true
}
}
false
}
then in oncreate you can set the above listener to your view
mDataBinding?.navigation?.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener)