底部导航栏在Android应用中随处可见,今天使用ViewPager+RadioGroup+Fragment这三个控件来实现此功能。前面写了有三种实现方式,有兴趣可以去看看,
Android 底部导航栏(一、BottomNavigationView+Menu+Fragment)_&岁月不待人&的博客-CSDN博客_android 底部导航栏
Android 底部导航栏(二、自定义View+Fragment)_&岁月不待人&的博客-CSDN博客
Android 底部导航栏(三、ViewPager+TabLayout+Fragment)简单易懂_&岁月不待人&的博客-CSDN博客
Fragment用于承载和展示内容,Viewpager用于界面的切换,RadioGroup用于展示导航栏和点击事件通知ViewPager切换页面。
第一步:布局代码,主要控件就是ViewPager和RadioGroup,再往里面放五个RadioButton子项。
- "1.0" encoding="utf-8"?>
- <layout xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools">
-
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@color/white"
- android:orientation="vertical">
-
- <androidx.appcompat.widget.AppCompatTextView
- android:id="@+id/nav_text"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="20dp"
- android:gravity="center"
- android:padding="4dp"
- android:text="ViewPager+RadioGroup+Fragment"
- android:textColor="@color/black"
- android:textSize="18sp"
- android:textStyle="bold" />
-
- <androidx.viewpager.widget.ViewPager
- android:id="@+id/fragment_container_viewpager"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_above="@id/nav_radiogroup"
- android:layout_below="@id/nav_text" />
-
- <View
- android:layout_width="match_parent"
- android:layout_height="0.3dp"
- android:layout_above="@id/nav_radiogroup"
- android:background="@color/tab_color_false" />
-
- <RadioGroup
- android:id="@+id/nav_radiogroup"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_alignParentBottom="true"
- android:background="@color/white"
- android:orientation="horizontal">
-
- <RadioButton
- android:id="@+id/nav_radio_button_1"
- style="@style/radiobutton"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:drawableTop="@drawable/food_avocado"
- android:text="首页"
- android:textColor="@drawable/selector_main_rb_text_color" />
-
- <RadioButton
- android:id="@+id/nav_radio_button_2"
- style="@style/radiobutton"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:drawableTop="@drawable/food_bread"
- android:text="游戏"
- android:textColor="@drawable/selector_main_rb_text_color" />
-
- <RadioButton
- android:id="@+id/nav_radio_button_3"
- style="@style/radiobutton"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:drawableTop="@drawable/food_cake"
- android:text="学习"
- android:textColor="@drawable/selector_main_rb_text_color" />
-
- <RadioButton
- android:id="@+id/nav_radio_button_4"
- style="@style/radiobutton"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:drawableTop="@drawable/food_eggyolkcake"
- android:text="放松"
- android:textColor="@drawable/selector_main_rb_text_color" />
-
- <RadioButton
- android:id="@+id/nav_radio_button_5"
- style="@style/radiobutton"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:drawableTop="@drawable/food_cookie"
- android:text="我的"
- android:textColor="@drawable/selector_main_rb_text_color" />
- RadioGroup>
- RelativeLayout>
- layout>
RadioButton的textColor的xml代码:选中为蓝色,未选中为黑色
- "1.0" encoding="utf-8"?>
- <selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:color="@color/blue" android:state_checked="true"/>
- <item android:color="@color/black" android:state_checked="false"/>
- selector>
RadioButton的style属性代码:在style.xml文件里
- <style name="radiobutton">
-
- <item name="android:layout_weight">1item>
- <item name="android:layout_width">0dpitem>
- <item name="android:drawablePadding">4dpitem>
- <item name="android:layout_height">wrap_contentitem>
- <item name="android:button">@nullitem>
- <item name="android:gravity">centeritem>
- <item name="android:textSize">12spitem>
- <item name="android:textColor">@drawable/selector_main_rb_text_coloritem>
- style>
eg:
1.设置weight都为1,这样的话子项的宽度都会是一样的。
2.drawablePadding属性,是为了让图片和文字有一点间距,好看些。
3.button为null,这样就可以去掉radioButton的那个不好看的默认按钮。
第二步:业务逻辑代码
- package com.example.lxview.lxhome.func.nav.activity
-
- import android.widget.RadioGroup
- import androidx.fragment.app.Fragment
- import androidx.fragment.app.FragmentPagerAdapter
- import androidx.viewpager.widget.ViewPager
- import com.example.lxview.R
- import com.example.lxview.base.activity.BaseBindActivity
- import com.example.lxview.base.fragment.BaseFragment
- import com.example.lxview.databinding.NavViewpagerRadiogroupActivityLayoutBinding
- import com.example.lxview.home.fragment.*
- /**
- * author: 李 祥
- * date: 2022/6/28 8:48 下午
- * description:
- */
- class NavViewPagerRadioGroupActivity : BaseBindActivity<NavViewpagerRadiogroupActivityLayoutBinding>() {
-
- override val layout: Int
- get() = R.layout.nav_viewpager_radiogroup_activity_layout
-
- private lateinit var homeFragment: HomeFragment
- private lateinit var toolsFragment: ToolsFragment
- private lateinit var relaxFragment: RelaxFragment
- private lateinit var viewPager: ViewPager
- private lateinit var radioGroup: RadioGroup
- private lateinit var meFragment: MineFragment
- private lateinit var playFragment: PlayFragment
- private lateinit var fragments: Array
- private val titles = arrayOf("首页", "视频", "用户", "音乐", "我的")
-
-
- override fun initView() {
- initFragment()
- viewPager = mBinding.fragmentContainerViewpager
- radioGroup = mBinding.navRadiogroup //绑定fragment列表
- viewPager.adapter = object : FragmentPagerAdapter(supportFragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
- override fun getCount(): Int {
- return fragments.size
- }
-
- override fun getItem(position: Int): Fragment {
- return fragments[position]
- }
-
- override fun getPageTitle(position: Int): CharSequence {
- return titles[position]
- }
- }
- }
-
- override fun initListener() {
-
- radioGroup.setOnCheckedChangeListener { _, checkedId ->
- when (checkedId) { //点击切换viewpager页面
- R.id.nav_radio_button_1 -> {
- viewPager.currentItem = 0
- }
- R.id.nav_radio_button_2 -> {
- viewPager.currentItem = 1
- }
- R.id.nav_radio_button_3 -> {
- viewPager.currentItem = 2
- }
- R.id.nav_radio_button_4 -> {
- viewPager.currentItem = 3
- }
- R.id.nav_radio_button_5 -> {
- viewPager.currentItem = 4
- }
- }
- }
- viewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
- override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
- }
-
- override fun onPageSelected(position: Int) { //当页面左右滑动发生改变时,radiogroup也改变子项的选择状态
- when (position) {
- 0 -> radioGroup.check(R.id.nav_radio_button_1)
- 1 -> radioGroup.check(R.id.nav_radio_button_2)
- 2 -> radioGroup.check(R.id.nav_radio_button_3)
- 3 -> radioGroup.check(R.id.nav_radio_button_4)
- 4 -> radioGroup.check(R.id.nav_radio_button_5)
- }
- }
-
- override fun onPageScrollStateChanged(state: Int) {
- }
-
- })
- }
-
- private fun initFragment() {
- homeFragment = HomeFragment()
- toolsFragment = ToolsFragment()
- relaxFragment = RelaxFragment()
- meFragment = MineFragment()
- playFragment = PlayFragment()
- fragments = arrayOf(homeFragment, toolsFragment, playFragment, relaxFragment, meFragment)
- }
- }
关于radioGroup和Viewpager的互相监听切换都写在代码里了,代码也注释了,如果想在点击item或者左右滑动后更改图片,也可以在这两个监听事件里进行更改,也可以直接设置drawableTop的资源文件,改成selector xml文件,比如在drawable先新建一个drawable_my_selector.xml文件
- "1.0" encoding="utf-8"?>
- <selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:drawable="@mipmap/icon_checked_my" android:state_checked="true" />
- <item android:drawable="@mipmap/icon_normal_my" android:state_checked="false" />
- selector>
然后在最上边的xml布局文件里将drawableTop属性更改为: android:drawableTop="@drawable/drawable_my_selector"
- .....
- <RadioButton
- android:id="@+id/nav_radio_button_5"
- style="@style/radiobutton"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:drawableTop="@drawable/drawable_my_selector"
- android:text="我的"
- android:textColor="@drawable/selector_main_rb_text_color" />
- ......
-
总结:总的来说,底部导航栏的实现方式有很多种,也很简单,怎样选择可以根据自己的喜好和需求来实现,有时候子项大小不一啊,各种过度动画之类的也会影响自己的选择。关于底部导航栏的文章我就写这四章了,当然并不是只有这些实现方式,也可以有其他的组合方式,或者其他的实现方法。