最简单的实现方式就是使用系统自动生成的模板页面,但是有时候会有一些问题,特别是需要去除【ActionBar】的情况下,这种情况下使用系统的模板页面就不好用了,此时可以使用下面这种解决方式。
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/navigation_home"
android:icon="@drawable/bottom_home_select"
android:title="预览" />
<item
android:id="@+id/navigation_statistics"
android:icon="@drawable/bottom_statis_select"
android:title="统计" />
<item
android:id="@+id/navigation_notifications"
android:icon="@drawable/bottom_notif_select"
android:title="通知" />
<item android:id="@+id/navigation_myset"
android:icon="@drawable/bottom_myset_select"
android:title="设置"/>
</menu>
本文中需要显示四个图标,所以需要做四个选择切换背景
其中这四个切换背景设置是一样的,这里就贴一个出来
【bottom_home_select】的代码
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_home_select" android:state_selected="true" />
<item android:drawable="@drawable/ic_home" android:state_selected="false" />
</selector>
然后这些切换效果添加在第一步中的【bottom_nav_menu】代码中
一般来说,文字切换效果的颜色是和图标颜色切换颜色是对应的
这个【color】一般是需要我们自己创建文件夹,在文件夹中创建文件【nav_bottom_txt_select】
代码展示
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#4878E3" android:state_selected="true" />
<item android:color="#B6B6B6" android:state_selected="false" />
</selector>
【BottomNavigationView】是Android Studio自带就有,但是【ViewPage2】需要我们进行依赖导入,而【ViewPage2】又依赖【Recyclerview】,所以需要导入这两个依赖。
implementation 'androidx.viewpager2:viewpager2:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.2.1'
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/nav_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:background="#ffffff"
//导航页面底部文字选择切换效果
app:itemTextColor="@color/nav_bottom_txt_select"
//文字显示模式(下面讲述)
app:labelVisibilityMode="labeled"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
//添加我们前面设置的menu
app:menu="@menu/bottom_nav_menu" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/nav_viewpage2"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toTopOf="@id/nav_view"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
我们底部栏有四个按钮,所以我们需要创建四个【Fragment】,所以我们这边会有四个【Fragment】页面,再次不再叙述。
创建四个【Fragment】页面,分别命名【HomeFragment】、【StatisticsFragment】、【NotificationsFragment】、【MySetFragment】(里面什么都没有,就是一个空页面)。
因为ViewPage2是依赖RecyclerView实现的,所以需要像使用Recyclerview一样创建一个适配器
【Java】版本
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import java.util.List;
/**
* 作者 ldd
* 日期 2023/2/7
*/
public class ViewPageAdapter extends FragmentStateAdapter {
private List<Fragment> list;
public ViewPageAdapter(@NonNull FragmentActivity fragmentActivity,
List<Fragment> fragmentList) {
super(fragmentActivity);
list = fragmentList;
}
@NonNull
@Override
public Fragment createFragment(int position) {
return list.get(position);
}
@Override
public int getItemCount() {
return list.size();
}
}
【Kotlin】版本
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.viewpager2.adapter.FragmentStateAdapter
/**
* 作者 ldd
* 日期 2023/2/7
*/
open class ViewPager2Adapter(
fa: FragmentActivity,
private val list: MutableList<Fragment>
) : FragmentStateAdapter(fa) {
override fun getItemCount(): Int {
return list.size
}
override fun createFragment(position: Int): Fragment {
return list[position]
}
}
下面使用的是【Kotlin】版本的
首先要去除系统主题的颜色,换成我们自定义的
//去除自带的选中颜色,去除后文字和图片选择效果就是跟我们自定义的效果一样
binding.navView.itemIconTintList = null
//将所有的【Fragment】添加到【ViewPager2】中
val fragmentList: MutableList<Fragment> = ArrayList()
fragmentList.add(HomeFragment())
fragmentList.add(StatisticsFragment())
fragmentList.add(NotificationsFragment())
fragmentList.add(MySetFragment())
binding.navViewpage2.adapter = ViewPager2Adapter(this, fragmentList)
//当viewpage2页面切换时nav导航图标也跟着切换
binding.navViewpage2.registerOnPageChangeCallback(object :
ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
super.onPageSelected(position)
binding.navView.menu.getItem(position).isChecked = true
}
})
//当nav导航点击切换时,viewpager2也跟着切换页面
binding.navView.setOnItemSelectedListener { item ->
when (item.itemId) {
R.id.navigation_home -> {
binding.navViewpage2.currentItem = 0
return@setOnItemSelectedListener true
}
R.id.navigation_statistics -> {
binding.navViewpage2.currentItem = 1
return@setOnItemSelectedListener true
}
R.id.navigation_notifications -> {
binding.navViewpage2.currentItem = 2
return@setOnItemSelectedListener true
}
R.id.navigation_myset -> {
binding.navViewpage2.currentItem = 3
return@setOnItemSelectedListener true
}
}
false
}
此时底部导航栏已经实现。
在设置bottomNavigationView的布局文件时,有个属性【labelVisibilityMode】
此属性有四个值
显示效果
【BottomNavigationView】自带此功能
当设置
var bride = binding.navView.getOrCreateBadge(R.id.navigation_notifications)
此时导航栏对应的item位置会显示小红点
如果给bride设置一个值
bride.number = 15
backgroundColor :设置角标背景色
badgeGravity :设置角标的显示位置
TOP_START,
TOP_END,
BOTTOM_START,
BOTTOM_END
badgeTextColor:设置角标显示的数字颜色
maxCharacterCount:最多显示几位数字
如果设置为2,number设置为15