效果如下图:
1. 在 build.gradle(Module:app) 的 dependencies{ ... }中引用
//BottomBar(方法1)
implementation 'com.roughike:bottom-bar:2.3.1'
// BottomNavigationView(方法2)
implementation 'com.google.android.material:material:1.1.0'
2.在activity_main.xmlz中设置
方法1:
<!--FrameLayout(用于多Fragment切换)-->
<FrameLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<!--引用的BottomBar-->
<com.roughike.bottombar.BottomBar
android:id="@+id/bottomBar"
android:layout_width="match_parent"
android:layout_height="60dp"
app:bb_titleTextAppearance="@style/TextAppearance.AppCompat.Large"
android:layout_alignParentBottom="true"
app:bb_tabXmlResource="@xml/bottombar_tabs" />
<!--
<com.roughike.bottombar.BottomBar
android:id="@+id/bottomBar"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_alignParentBottom="true"
app:bb_tabXmlResource="@xml/bottombar_tabs_three"
app:bb_tabletMode="true"
app:bb_behavior="shifting|shy|underNavbar"
app:bb_inActiveTabAlpha="0.6"
app:bb_activeTabAlpha="1"
app:bb_inActiveTabColor="#222222"
app:bb_activeTabColor="@color/colorPrimary"
app:bb_titleTextAppearance="@style/MyTextAppearance"
app:bb_titleTypeFace="fonts/MySuperDuperFont.ttf"
app:bb_showShadow="true" />
bb_tabXmlResource:
设置标签的 xml 资源标识,在 res/xml/ 目录下。
bb_tabletMode:
是否是平板模式。true:是;false:不是。
bb_behavior:(三种模式)
shifting: 选定的标签比其他的更宽。
shy: 将 Bottombar 放在 Coordinatorlayout 它会自动隐藏在滚动!(需要特定的布局)
underNavbar: 正常模式(默认)。
bb_inActiveTabAlpha:
没选中时标签的透明度,icon 和 titiles 有用。(取值:0-1)
bb_activeTabAlpha:
选中时标签的透明度,与上一个相对应。(取值:0-1)
bb_inActiveTabColor:
没选时标签的颜色,icon 和 titiles 有用。
bb_activeTabColor:
选中时标签的颜色,与一个相对应。
bb_badgeBackgroundColor:
设置 Badges 的背景色,就是右上角显示数字那个。
bb_titleTextAppearance:
利用 style 重新设置自定的格式,例如:大小、加粗等。
bb_titleTypeFace:
设置自定的字体, 例: app:bb_titleTypeFace="fonts/MySuperDuperFont.ttf"。
将字体放在 src/main/assets/fonts/MySuperDuperFont.ttf 路径下,
只需要写 fonts/MySuperDuperFont.ttf 即可,将自动填充。
bb_showShadow:
控制阴影是否显示或隐藏,类似于蒙板,默认为true。
-->
方法2:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".NavMenuActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorWhite">
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<!--分割线-->
<View
android:layout_width="match_parent"
android:layout_height="0.3dp"
android:layout_above="@+id/bottom_nav"
android:background="@color/colorDivision"/>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_nav"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
app:menu="@menu/bottom_nav"
android:background="@color/colorWhite"/>
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
3.创建底部菜单栏
方法1:
在res文件夹下新建xml文件夹,并创建bottombar_tabs.xml
注意:<tabs></tabs>和<tab></tab>标签需要手写(有时没有提示)
<?xml version="1.0" encoding="utf-8"?>
<tabs>
<tab
id="@+id/tab_home"
icon="@mipmap/home"
title="首页"/>
<tab
id="@+id/tab_project"
icon="@mipmap/project"
title="项目"/>
<tab
id="@+id/tab_message"
icon="@mipmap/message"
title="消息"/>
<tab
id="@+id/tab_my"
icon="@mipmap/my"
title="我"/>
<!--
<tab
id="@+id/tab_recents"
title="Recents"
icon="@drawable/empty_icon"// 手机端图标尺寸最后32x32太大会遮盖文字
inActiveColor="#00FF00"
activeColor="#FF0000"
barColorWhenSelected="#FF0000"
badgeBackgroundColor="#FF0000" />
inActiveColor:
未被选择时,标签的颜色,作用于 icon 和 title。
activeColor:
被选择时,标签的颜色,作用于 icon 和 title,与上面相对应。
barColorWhenSelected:
当该标签被选择时,整个 BottomBar 的背景色。(就是一点,整个底部渐变的那个颜色)
badgeBackgroundColor:
设置 Badges 的背景色,就是右上角显示数字那个。
-->
</tabs>
方法2:
在res文件夹下新建menu文件夹,并在menu文件夹下创建bottom_nav.xml
bottom_nav.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/bottom_home"
android:icon="@mipmap/ic_launcher"
android:title="首页"/>
<item
android:id="@+id/bottom_info"
android:icon="@mipmap/ic_launcher"
android:title="资讯"/>
<item
android:id="@+id/bottom_my"
android:icon="@mipmap/ic_launcher"
android:title="我的"/>
</menu>
4.创建Fragment工厂类
package com.example.fragment;
import android.support.v4.app.Fragment;
import com.example.zhang.masterofsurveying.R;
/**
* Fragment工厂类
* */
public class FragmentFactory {
public static final String TAG = "FragmentFactory";
private static FragmentFactory sFragmentFactory;
private static HomePageFragment homePageFragment;
private static ProjectPageFragment projectPageFragment;
private static MessagePageFragment messagePageFragment;
private static MyPageFragment myPageFragment;
/**
* 构造函数
* */
public FragmentFactory(){}
public static FragmentFactory getInstance(){
if (sFragmentFactory == null){
// 异步加锁, 保证同时只有一个访问
synchronized (FragmentFactory.class){
if (sFragmentFactory==null){
sFragmentFactory = new FragmentFactory();
}
}
}
return sFragmentFactory;
}
public Fragment getFragment(int tabId){
switch (tabId){
case R.id.tab_home:
return getHomePageFragment();
case R.id.tab_project:
return getProjectPageFragment();
case R.id.tab_message:
return getMessagePageFragment();
case R.id.tab_my:
return getMyPageFragment();
}
// 默认返回主界面
return getHomePageFragment();
}
/**
* 主界面
* */
private static Fragment getHomePageFragment() {
if(homePageFragment==null){
homePageFragment = new HomePageFragment();
}
return homePageFragment;
}
/**
* 项目界面
* */
private static Fragment getProjectPageFragment() {
if(projectPageFragment==null){
projectPageFragment = new ProjectPageFragment();
}
return projectPageFragment;
}
/**
* 消息界面
* */
private static Fragment getMessagePageFragment() {
if(messagePageFragment==null){
messagePageFragment = new MessagePageFragment();
}
return messagePageFragment;
}
/**
* 我的界面
* */
private static Fragment getMyPageFragment(){
if (myPageFragment==null){
myPageFragment = new MyPageFragment();
}
return myPageFragment;
}
}
5.根据需求创建对应的fragment,例子如下
我共创建四个fragment,只给出一个例子,其他fragment写法一样,对应的页面(fragment_xxx.xml)就不写了
package com.example.fragment;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.zhang.masterofsurveying.R;
public class HomePageFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater,@Nullable ViewGroup container,@Nullable Bundle savedInstanceState) {
super.onCreateView(inflater,container,savedInstanceState);
return View.inflate(getContext(),R.layout.fragment_home_page, null);
}
}
6.在MainActivity.java中使用如下
方法1:
/**
* 初始化BottomBar
* */
public void initBottomBar(){
bottomBar = findViewById(R.id.bottomBar);
final FragmentManager fragmentManager = getSupportFragmentManager();
bottomBar.setOnTabSelectListener(new OnTabSelectListener() {
@Override
public void onTabSelected(int tabId) {
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.content, FragmentFactory.getInstance().getFragment(tabId)).commit();
}
});
}
方法2:
private void initBottomNav(){
bottonNavBar = findViewById(R.id.bottom_nav);
final FragmentManager fragmentManager = getSupportFragmentManager();
bottonNavBar.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.fragment_container,FragmentFactory.getInstance().getFragment(item.getItemId())).commit();
return true;
}
});
}