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

简介: 底部导航栏在Android应用中随处可见,今天使用ViewPager+RadioGroup+Fragment这三个控件来实现此功能。前面写了有三种实现方式,有兴趣可以去看看

一、基本介绍


底部导航栏在Android应用中随处可见,今天使用ViewPager+RadioGroup+Fragment这三个控件来实现此功能。前面写了有三种实现方式,有兴趣可以去看看


二、实现原理


Fragment用于承载和展示内容,Viewpager用于界面的切换,RadioGroup用于展示导航栏和点击事件通知ViewPager切换页面。


三、实现过程


第一步:布局代码,主要控件就是ViewPager和RadioGroup,再往里面放五个RadioButton子项。

<?xml version="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代码:选中为蓝色,未选中为黑色
<?xml version="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">
    <!--底部导航radiobutton的属性设置-->
        <item name="android:layout_weight">1</item>
        <item name="android:layout_width">0dp</item>
        <item name="android:drawablePadding">4dp</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:button">@null</item>
        <item name="android:gravity">center</item>
        <item name="android:textSize">12sp</item>
        <item name="android:textColor">@drawable/selector_main_rb_text_color</item>
    </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<BaseFragment>
    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文件
<?xml version="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" />
......

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


相关文章
|
7月前
|
Android开发 容器
35. 【Android教程】视频页面:ViewPager
35. 【Android教程】视频页面:ViewPager
67 3
|
3月前
|
缓存 前端开发 Android开发
Android实战之如何截取Activity或者Fragment的内容?
本文首发于公众号“AntDream”,介绍了如何在Android中截取Activity或Fragment的屏幕内容并保存为图片。包括截取整个Activity、特定控件或区域的方法,以及处理包含RecyclerView的复杂情况。
33 3
|
5月前
|
Android开发
Android使用ViewPager做无限轮播,人为滑动时停止
Android使用ViewPager做无限轮播,人为滑动时停止
101 2
|
8月前
|
XML 存储 Android开发
Android技能树 — Fragment总体小结,2024年最新腾讯面试gm
Android技能树 — Fragment总体小结,2024年最新腾讯面试gm
|
8月前
|
Android开发
Android使用ViewPager实现图片轮播系列之三:手动滑动 + 左右箭头(1)
Android使用ViewPager实现图片轮播系列之三:手动滑动 + 左右箭头(1)
|
8月前
|
XML Android开发 数据格式
Fragment的使用,零基础入门android逆向视频课程
Fragment的使用,零基础入门android逆向视频课程
|
2月前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台策略
在移动应用开发的战场上,安卓和iOS两大阵营各据一方。随着技术的演进,跨平台开发框架成为开发者的新宠,旨在实现一次编码、多平台部署的梦想。本文将探讨跨平台开发的优势与挑战,并分享实用的开发技巧,帮助开发者在安卓和iOS的世界中游刃有余。
|
1月前
|
搜索推荐 前端开发 API
探索安卓开发中的自定义视图:打造个性化用户界面
在安卓应用开发的广阔天地中,自定义视图是一块神奇的画布,让开发者能够突破标准控件的限制,绘制出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战技巧,逐步揭示如何在安卓平台上创建和运用自定义视图来提升用户体验。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开新的视野,让你的应用在众多同质化产品中脱颖而出。
57 19
|
2月前
|
IDE Java 开发工具
移动应用与系统:探索Android开发之旅
在这篇文章中,我们将深入探讨Android开发的各个方面,从基础知识到高级技术。我们将通过代码示例和案例分析,帮助读者更好地理解和掌握Android开发。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和技巧。让我们一起开启Android开发的旅程吧!
|
1月前
|
JSON Java API
探索安卓开发:打造你的首个天气应用
在这篇技术指南中,我们将一起潜入安卓开发的海洋,学习如何从零开始构建一个简单的天气应用。通过这个实践项目,你将掌握安卓开发的核心概念、界面设计、网络编程以及数据解析等技能。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供一个清晰的路线图和实用的代码示例,帮助你在安卓开发的道路上迈出坚实的一步。让我们一起开始这段旅程,打造属于你自己的第一个安卓应用吧!
64 14