• Android 底部导航栏(四、ViewPager+RadioGroup+Fragment)简单易懂


    一、基本介绍

    底部导航栏在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. "1.0" encoding="utf-8"?>
    2. <layout xmlns:app="http://schemas.android.com/apk/res-auto"
    3. xmlns:tools="http://schemas.android.com/tools">
    4. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    5. android:layout_width="match_parent"
    6. android:layout_height="match_parent"
    7. android:background="@color/white"
    8. android:orientation="vertical">
    9. <androidx.appcompat.widget.AppCompatTextView
    10. android:id="@+id/nav_text"
    11. android:layout_width="match_parent"
    12. android:layout_height="wrap_content"
    13. android:layout_marginTop="20dp"
    14. android:gravity="center"
    15. android:padding="4dp"
    16. android:text="ViewPager+RadioGroup+Fragment"
    17. android:textColor="@color/black"
    18. android:textSize="18sp"
    19. android:textStyle="bold" />
    20. <androidx.viewpager.widget.ViewPager
    21. android:id="@+id/fragment_container_viewpager"
    22. android:layout_width="match_parent"
    23. android:layout_height="match_parent"
    24. android:layout_above="@id/nav_radiogroup"
    25. android:layout_below="@id/nav_text" />
    26. <View
    27. android:layout_width="match_parent"
    28. android:layout_height="0.3dp"
    29. android:layout_above="@id/nav_radiogroup"
    30. android:background="@color/tab_color_false" />
    31. <RadioGroup
    32. android:id="@+id/nav_radiogroup"
    33. android:layout_width="match_parent"
    34. android:layout_height="wrap_content"
    35. android:layout_alignParentBottom="true"
    36. android:background="@color/white"
    37. android:orientation="horizontal">
    38. <RadioButton
    39. android:id="@+id/nav_radio_button_1"
    40. style="@style/radiobutton"
    41. android:layout_width="wrap_content"
    42. android:layout_height="wrap_content"
    43. android:drawableTop="@drawable/food_avocado"
    44. android:text="首页"
    45. android:textColor="@drawable/selector_main_rb_text_color" />
    46. <RadioButton
    47. android:id="@+id/nav_radio_button_2"
    48. style="@style/radiobutton"
    49. android:layout_width="wrap_content"
    50. android:layout_height="wrap_content"
    51. android:drawableTop="@drawable/food_bread"
    52. android:text="游戏"
    53. android:textColor="@drawable/selector_main_rb_text_color" />
    54. <RadioButton
    55. android:id="@+id/nav_radio_button_3"
    56. style="@style/radiobutton"
    57. android:layout_width="wrap_content"
    58. android:layout_height="wrap_content"
    59. android:drawableTop="@drawable/food_cake"
    60. android:text="学习"
    61. android:textColor="@drawable/selector_main_rb_text_color" />
    62. <RadioButton
    63. android:id="@+id/nav_radio_button_4"
    64. style="@style/radiobutton"
    65. android:layout_width="wrap_content"
    66. android:layout_height="wrap_content"
    67. android:drawableTop="@drawable/food_eggyolkcake"
    68. android:text="放松"
    69. android:textColor="@drawable/selector_main_rb_text_color" />
    70. <RadioButton
    71. android:id="@+id/nav_radio_button_5"
    72. style="@style/radiobutton"
    73. android:layout_width="wrap_content"
    74. android:layout_height="wrap_content"
    75. android:drawableTop="@drawable/food_cookie"
    76. android:text="我的"
    77. android:textColor="@drawable/selector_main_rb_text_color" />
    78. RadioGroup>
    79. RelativeLayout>
    80. layout>

    RadioButton的textColor的xml代码:选中为蓝色,未选中为黑色

    1. "1.0" encoding="utf-8"?>
    2. <selector xmlns:android="http://schemas.android.com/apk/res/android">
    3. <item android:color="@color/blue" android:state_checked="true"/>
    4. <item android:color="@color/black" android:state_checked="false"/>
    5. selector>

    RadioButton的style属性代码:在style.xml文件里

    1. <style name="radiobutton">
    2. <item name="android:layout_weight">1item>
    3. <item name="android:layout_width">0dpitem>
    4. <item name="android:drawablePadding">4dpitem>
    5. <item name="android:layout_height">wrap_contentitem>
    6. <item name="android:button">@nullitem>
    7. <item name="android:gravity">centeritem>
    8. <item name="android:textSize">12spitem>
    9. <item name="android:textColor">@drawable/selector_main_rb_text_coloritem>
    10. style>

    eg:

    1.设置weight都为1,这样的话子项的宽度都会是一样的。

    2.drawablePadding属性,是为了让图片和文字有一点间距,好看些。

    3.button为null,这样就可以去掉radioButton的那个不好看的默认按钮。

    第二步:业务逻辑代码

    1. package com.example.lxview.lxhome.func.nav.activity
    2. import android.widget.RadioGroup
    3. import androidx.fragment.app.Fragment
    4. import androidx.fragment.app.FragmentPagerAdapter
    5. import androidx.viewpager.widget.ViewPager
    6. import com.example.lxview.R
    7. import com.example.lxview.base.activity.BaseBindActivity
    8. import com.example.lxview.base.fragment.BaseFragment
    9. import com.example.lxview.databinding.NavViewpagerRadiogroupActivityLayoutBinding
    10. import com.example.lxview.home.fragment.*
    11. /**
    12. * author: 李 祥
    13. * date: 2022/6/28 8:48 下午
    14. * description:
    15. */
    16. class NavViewPagerRadioGroupActivity : BaseBindActivity<NavViewpagerRadiogroupActivityLayoutBinding>() {
    17. override val layout: Int
    18. get() = R.layout.nav_viewpager_radiogroup_activity_layout
    19. private lateinit var homeFragment: HomeFragment
    20. private lateinit var toolsFragment: ToolsFragment
    21. private lateinit var relaxFragment: RelaxFragment
    22. private lateinit var viewPager: ViewPager
    23. private lateinit var radioGroup: RadioGroup
    24. private lateinit var meFragment: MineFragment
    25. private lateinit var playFragment: PlayFragment
    26. private lateinit var fragments: Array
    27. private val titles = arrayOf("首页", "视频", "用户", "音乐", "我的")
    28. override fun initView() {
    29. initFragment()
    30. viewPager = mBinding.fragmentContainerViewpager
    31. radioGroup = mBinding.navRadiogroup //绑定fragment列表
    32. viewPager.adapter = object : FragmentPagerAdapter(supportFragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
    33. override fun getCount(): Int {
    34. return fragments.size
    35. }
    36. override fun getItem(position: Int): Fragment {
    37. return fragments[position]
    38. }
    39. override fun getPageTitle(position: Int): CharSequence {
    40. return titles[position]
    41. }
    42. }
    43. }
    44. override fun initListener() {
    45. radioGroup.setOnCheckedChangeListener { _, checkedId ->
    46. when (checkedId) { //点击切换viewpager页面
    47. R.id.nav_radio_button_1 -> {
    48. viewPager.currentItem = 0
    49. }
    50. R.id.nav_radio_button_2 -> {
    51. viewPager.currentItem = 1
    52. }
    53. R.id.nav_radio_button_3 -> {
    54. viewPager.currentItem = 2
    55. }
    56. R.id.nav_radio_button_4 -> {
    57. viewPager.currentItem = 3
    58. }
    59. R.id.nav_radio_button_5 -> {
    60. viewPager.currentItem = 4
    61. }
    62. }
    63. }
    64. viewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
    65. override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
    66. }
    67. override fun onPageSelected(position: Int) { //当页面左右滑动发生改变时,radiogroup也改变子项的选择状态
    68. when (position) {
    69. 0 -> radioGroup.check(R.id.nav_radio_button_1)
    70. 1 -> radioGroup.check(R.id.nav_radio_button_2)
    71. 2 -> radioGroup.check(R.id.nav_radio_button_3)
    72. 3 -> radioGroup.check(R.id.nav_radio_button_4)
    73. 4 -> radioGroup.check(R.id.nav_radio_button_5)
    74. }
    75. }
    76. override fun onPageScrollStateChanged(state: Int) {
    77. }
    78. })
    79. }
    80. private fun initFragment() {
    81. homeFragment = HomeFragment()
    82. toolsFragment = ToolsFragment()
    83. relaxFragment = RelaxFragment()
    84. meFragment = MineFragment()
    85. playFragment = PlayFragment()
    86. fragments = arrayOf(homeFragment, toolsFragment, playFragment, relaxFragment, meFragment)
    87. }
    88. }

    关于radioGroup和Viewpager的互相监听切换都写在代码里了,代码也注释了,如果想在点击item或者左右滑动后更改图片,也可以在这两个监听事件里进行更改,也可以直接设置drawableTop的资源文件,改成selector xml文件,比如在drawable先新建一个drawable_my_selector.xml文件

    1. "1.0" encoding="utf-8"?>
    2. <selector xmlns:android="http://schemas.android.com/apk/res/android">
    3. <item android:drawable="@mipmap/icon_checked_my" android:state_checked="true" />
    4. <item android:drawable="@mipmap/icon_normal_my" android:state_checked="false" />
    5. selector>

    然后在最上边的xml布局文件里将drawableTop属性更改为: android:drawableTop="@drawable/drawable_my_selector"

    1. .....
    2. <RadioButton
    3. android:id="@+id/nav_radio_button_5"
    4. style="@style/radiobutton"
    5. android:layout_width="wrap_content"
    6. android:layout_height="wrap_content"
    7. android:drawableTop="@drawable/drawable_my_selector"
    8. android:text="我的"
    9. android:textColor="@drawable/selector_main_rb_text_color" />
    10. ......

    总结:总的来说,底部导航栏的实现方式有很多种,也很简单,怎样选择可以根据自己的喜好和需求来实现,有时候子项大小不一啊,各种过度动画之类的也会影响自己的选择。关于底部导航栏的文章我就写这四章了,当然并不是只有这些实现方式,也可以有其他的组合方式,或者其他的实现方法。

  • 相关阅读:
    搭建自己的搜索引擎之四
    简单认识泛型【java】
    设计的思考,设计是什么? 优漫动游
    离线部署 python 3.x 版本
    AVR汇编(六):分支指令
    淘宝二面:MySQL里有2000万条数据,但是Redis中只存20万的数据,如何保证redis中的数据都是热点数据?
    麒麟系统开发笔记(十二):在国产麒麟系统上编译GDAL库、搭建基础开发环境和基础Demo
    2、ARM处理器概论
    辅助驾驶功能开发-功能规范篇(25)-1-全景影像AVM规范
    项目管理工具,帮助项目经理提高工作效率
  • 原文地址:https://blog.csdn.net/LoveFHM/article/details/127701954