Android底部导航栏创建——ViewPager + RadioGroup

Android底部导航栏有多种实现方式,本文详解其中的ViewPager + RadioGroup方式的实现步骤。

我们先来看以下看一下最终做出的效果,使大家有个基本概念。

本结构特点:

1,ViewPager部分触摸左右滑动切换页面,RadioGroup部分中的RadioButton随着自己对应的ViewPager页面出现选中时的状态,包括改变背景颜色,

改变文字颜色,改变图片。其他RadioButton则是未被选中时的状态;

2,当用户点击RadioGroup部分中的RadioButton,被点击的RadioButton出现被选中时的颜色,ViewPager界面对应于RadioButton的页面会出现在当前界面。

可以看到,ViewPager和RadioGroup可以双向联动,不是单向传递。

下面我们通过一个实例完全弄懂ViewPager + RadioGroup结构的用法

首先创建出我们界面的布局,上边一个ViewPager,中间 一条分隔线,下边一个RadioGroup

我们在一个Activity的布局中创建如下的xml文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_main"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <!--上边为ViewPager-->

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        />

    <!--中间为一条分割线-->
    <View
        android:background="@color/divider"
        android:layout_width="match_parent"
        android:layout_height="1dp"/>

    <!--最下边为RadioGroup-->
    <RadioGroup
        android:id="@+id/radioGroup"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <!--第一个RadioButton-->
        <RadioButton
            android:id="@+id/button_1"
            android:text="button_1"
            android:button="@null"
            android:textColor="@color/radiobutton_color_selector"
            android:background="@drawable/radiobutton_bg_selector"
            android:gravity="center"
            android:layout_weight="1"
            android:drawableTop="@drawable/radiobutton_pic_selector"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <!--第二个RadioButton-->
        <RadioButton
            android:id="@+id/button_2"
            android:text="button_2"
            android:button="@null"
            android:textColor="@color/radiobutton_color_selector"
            android:background="@drawable/radiobutton_bg_selector"
            android:gravity="center"
            android:layout_weight="1"
            android:drawableTop="@drawable/radiobutton_pic_selector"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <!--第三个RadioButton-->
        <RadioButton
            android:id="@+id/button_3"
            android:text="button_3"
            android:button="@null"
            android:textColor="@color/radiobutton_color_selector"
            android:background="@drawable/radiobutton_bg_selector"
            android:gravity="center"
            android:layout_weight="1"
            android:drawableTop="@drawable/radiobutton_pic_selector"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <!--第四个RadioButton-->
        <RadioButton
            android:id="@+id/button_4"
            android:text="button_4"
            android:button="@null"
            android:textColor="@color/radiobutton_color_selector"
            android:background="@drawable/radiobutton_bg_selector"
            android:gravity="center"
            android:layout_weight="1"
            android:drawableTop="@drawable/radiobutton_pic_selector"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

    </RadioGroup>

</LinearLayout>

 布局中重要属性说明:

 ①ViewPager的android:layout_height属性值为0,android:layout_weight属性值为1。这两个属性值配合使用的意义是:

  在竖直方向上ViewPager占满父控件的剩余空间,也就是占据LinearLayout中除去分隔线和RadioGroup的剩余空间。

  关于android:layout_weight属性的详细用法请参考:android:layout_weight属性的使用方法总结 - chironmy - 博客园                      

 ②RadioButton的android:button属性值为@null。这个属性值的意义是,去除RadioGroup默认自带显示的小圆圈。

 ③RadioButton的android:gravity属性值为center。这个属性值的意义是,使RadioButton的内容(图片和文字)居中。注意,内容默认情况没有居中。

 ④RadioGroup的android:orientation属性值为horizontal。意为,水平布置其中的RadioButton。

 ⑤RadioButton的android:textColor属性值为@color/radiobutton_color_selector,是一个颜色状态选择器。颜色状态选择器就是一个定义在res/color目录

      下的xml文件,color目录需要我们手动创建。颜色状态选择器的代码如下:  

1

2

3

4

5

6

7

8

9

10

<?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:color="#f00" android:state_checked="true"/>

    <item android:color="#f00" android:state_pressed="true"/>

    <item android:color="#f00" android:state_selected="true"/>

    <!--没被选中时的颜色-->

    <item android:color="#000"/>

</selector>

关于状态选择器的更详细知识,请参考文章http://www.cnblogs.com/baipengzhan/p/6284682.html                       

⑥RadioButton的android:background属性值为@drawable/radiobutton_bg_selector,这一个背景状态选择器,用来改变背景颜色,代码如下:

1

2

3

4

5

6

7

8

9

10

<?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_selected="true" android:drawable="@color/radiobutton_bg_selected"/>

    <item android:state_checked="true" android:drawable="@color/radiobutton_bg_selected"/>

    <item android:state_pressed="true" android:drawable="@color/radiobutton_bg_selected"/>

    <!--未被选中-->

    <item android:drawable="@color/radiobutton_bg_normal" />

</selector>

这个状态选择器是放置在res/drawable目录下的一个普通状态选择器,该选择器的属性android:drawable的属性值不能直接设置颜色,

颜色要封装在values目录下的colors.xml文件中,否则出错。

⑦RadioButton的android:drawableTop属性值为@drawable/radiobutton_pic_selector,是一个普通的状态选择器,用来改变图片,代码如下:

1

2

3

4

5

6

7

8

9

10

<?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_selected="true" android:drawable="@mipmap/ic_selected"/>

    <item android:state_checked="true" android:drawable="@mipmap/ic_selected"/>

    <item android:state_pressed="true" android:drawable="@mipmap/ic_selected"/>

    <!--未被选中-->

    <item android:drawable="@mipmap/ic_launcher"/>

</selector>

该状态选择器同样放置在res/drawable目录下,选择器的属性值android:drawable属性值变为了图片,注意代码写到此处时,系统可能不会提示,

需要手动将该属性值添加进来。

更多关于状态选择器的知识请参考文章http://www.cnblogs.com/baipengzhan/p/6284682.html  

创建出ViewPager页面盛放的Fragment 

我们创建出对应于四个RadioButton的四个Fragment,每个Fragment中盛放一个TextView。下边只列出一个Fragment的写法,剩余的相似,请各位朋友自己写写哦。

public class Fragment_1 extends Fragment {

    private View mView;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        //注意View对象的重复使用,以便节省资源
        if(mView == null) {
            mView = inflater.inflate(R.layout.fragment_1_layout,container,false);
        }

        return mView;
    }
}

Fragment_1对应的布局:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:orientation="vertical"

    android:gravity="center"

    android:layout_width="match_parent"

    android:layout_height="match_parent">

    <!--创建TextView-->

    <TextView

        android:text="pager_1"

        android:textSize="28sp"

        android:textColor="#00f"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content" />

</LinearLayout>

在Activity中进行主要逻辑处理

我们在Activity中主要进行的工作如下:

①监听ViewPager,改变RadioGroup中的RadioButton;

②监听RadioGroup中的RadioButton,改变ViewPager;

代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

package com.example.chironmy.bottomnavigation;

import android.os.Bundle;

import android.support.v4.app.Fragment;

import android.support.v4.app.FragmentManager;

import android.support.v4.app.FragmentPagerAdapter;

import android.support.v4.view.ViewPager;

import android.support.v7.app.AppCompatActivity;

import android.view.View;

import android.view.ViewGroup;

import android.widget.RadioButton;

import android.widget.RadioGroup;

import java.util.ArrayList;

import java.util.List;

public class MainActivity extends AppCompatActivity implements View.OnClickListener,ViewPager.OnPageChangeListener{

    private ViewPager viewPager;

    private RadioGroup radioGroup;

    private RadioButton button_1;

    private RadioButton button_2;

    private RadioButton button_3;

    private RadioButton button_4;

    private Fragment_1 fragment_1;

    private Fragment_2 fragment_2;

    private Fragment_3 fragment_3;

    private Fragment_4 fragment_4;

    private List<Fragment> list;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        //初始化界面

        initView();

    }

    //初始化界面

    private void initView() {

        viewPager = (ViewPager) findViewById(R.id.viewpager);

        radioGroup = (RadioGroup) findViewById(R.id.radioGroup);

        //找到四个按钮

        button_1 = (RadioButton) findViewById(R.id.button_1);

        button_2 = (RadioButton) findViewById(R.id.button_2);

        button_3 = (RadioButton) findViewById(R.id.button_3);

        button_4 = (RadioButton) findViewById(R.id.button_4);

        //创建Fragment对象及集合

        fragment_1 = new Fragment_1();

        fragment_2 = new Fragment_2();

        fragment_3 = new Fragment_3();

        fragment_4 = new Fragment_4();

        //将Fragment对象添加到list中

        list = new ArrayList<>();

        list.add(fragment_1);

        list.add(fragment_2);

        list.add(fragment_3);

        list.add(fragment_4);

        //给viewPager设置适配器,以显示内容

        MyViewPagerAdapter adapter = new MyViewPagerAdapter(getSupportFragmentManager());

        viewPager.setAdapter(adapter);

        //设置RadioGroup开始时设置的按钮,设置第一个按钮为默认值

        radioGroup.check(R.id.button_1);

        //设置Viewpager第一次显示的页面

        viewPager.setCurrentItem(0,true);

        //设置按钮点击监听

        button_1.setOnClickListener(this);

        button_2.setOnClickListener(this);

        button_3.setOnClickListener(this);

        button_4.setOnClickListener(this);

        //设置ViewPager页面监听

        viewPager.addOnPageChangeListener(this);

    }

    @Override

    public void finish() {

        ViewGroup viewGroup = (ViewGroup) getWindow().getDecorView();

        viewGroup.removeAllViews();

        super.finish();

    }

    //创建ViewPager盛放Fragment的适配器类

    public class MyViewPagerAdapter extends FragmentPagerAdapter {

        public MyViewPagerAdapter(FragmentManager fm) {

            super(fm);

        }

        //返回每个position对应的Fragment对象

        @Override

        public Fragment getItem(int position) {

            return list.get(position);

        }

        //返回list的长度,也就是Fragment对象的个数

        @Override

        public int getCount() {

            return list.size();

        }

    }

    //处理点击的方法

    @Override

    public void onClick(View v) {

        //我们根据参数的id区别不同按钮

        //不同按钮对应着不同的ViewPager页面

        switch (v.getId()) {

            case R.id.button_1:

                viewPager.setCurrentItem(0,true);

                break;

            case R.id.button_2:

                viewPager.setCurrentItem(1,true);

                break;

            case R.id.button_3:

                viewPager.setCurrentItem(2,true);

                break;

            case R.id.button_4:

                viewPager.setCurrentItem(3,true);

                break;

            default:

                break;

        }

    }

    //处理页面变化的方法

    @Override

    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    //本文章中我们使用这个方法,本方法处理页面变化后,也就是切换了不同的页面后所做的操作

    @Override

    public void onPageSelected(int position) {

        //根据当前展示的ViewPager页面,使RadioGroup对应的按钮被选中

        switch (position) {

            case 0:

                radioGroup.check(R.id.button_1);

                break;

            case 1:

                radioGroup.check(R.id.button_2);

                break;

            case 2:

                radioGroup.check(R.id.button_3);

                break;

            case 3:

                radioGroup.check(R.id.button_4);

                break;

            default:

                break;

        }

    }

    @Override

    public void onPageScrollStateChanged(int state) {

    }

}

注意:在onClick方法中,viewPager的setCurrentItem方法中的第二个参数的意义是:

            当该参数为true时,viewPager换页时是平滑的换页,会有页面移动的效果;

            该参数为false时,viewPager换页效果没有平滑的移动,页面会直接出现。

            该方法有一个参数的重载方法,默认有平滑换页效果。  

以上代码中很多可以优化,比如xml文件中大量的属性可以提取样式,等等,这里列出只是为了方便更多水平的读者读懂,请谅解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/353946.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

XXL-JOB

SpringTask这种任务只能放在单机节点下&#xff0c;就是说一个程序只跑一份的情况下&#xff0c;用SpringTask做定时任务没有什么问题&#xff0c;而且很好用&#xff0c;但是一旦这个程序需要运行多份&#xff0c;定时任务用SpringTask就不行了。多份代码重复执行了。 要解决…

React中文官网已经搬迁了,原网址内容将不再更新

注意1&#xff1a;React中文官网已经搬迁至-React 官方中文文档&#xff0c;原网址内容将不再更新 注意2&#xff1a;React官网已经将React的定义由“用于构建用户界面的 JavaScript 库”更改为“用于构建 Web 和原生交互界面的库”。

Power ModeII 插件的下载与使用-----idea

下载 Marketplace里面搜索下载即可 使用 下载后重启软件就可以用了 下面是一些关于Power ModeII &#xff0c;我的个性化设置截图 以及相关设置解释 插件或扩展的设置面板【用于给代码编辑器或集成开发环境&#xff08;IDE&#xff09;添加视觉效果】 主要设置 ENTER POWE…

GEE数据集——2024 年日本海地震的紧急观测数据

2024 年日本海地震的紧急观测数据 2024 年日本海地震发生在 2024 年 1 月 1 日下午 4:00 后&#xff08;日本时间&#xff09;&#xff0c;造成了重大损失&#xff0c;包括多处建筑物倒塌、山体滑坡和火灾。应日本国内防灾机构的请求&#xff0c;JAXA 利用 ALOS-2 对灾害发生当…

Jenkins邮件推送配置

目录 涉及Jenkins插件&#xff1a; 邮箱配置 什么是授权码 在第三方客户端/服务怎么设置 IMAP/SMTP 设置方法 POP3/SMTP 设置方法 获取授权码&#xff1a; Jenkins配置 从Jenkins主面板System configuration>System进入邮箱配置 在Email Extension Plugin 邮箱插件…

操作日志应记录编辑的前后内容变化

总体思路是增加一个注解类&#xff0c;将注解加到要进行记录变化的Java类属性上却可。 上代码&#xff1a; 1. 实现注解类&#xff1a; Target(ElementType.FIELD) Retention(RetentionPolicy.RUNTIME) public interface FieldName {String value();boolean isIgnoreNull()…

六、VTK创建平面vtkPlaneSource

vtkPlaneSource创建位于平面中的四边形数组 先看看效果图: vtkPlaneSource 创建一个 m x n 个四边形数组,这些四边形在平面中排列为规则平铺。通过指定一个原点来定义平面,然后指定另外两个点,这两个点与原点一起定义平面的两个轴。这些轴不必是正交的 - 因此您可以创建平行…

基于yolov5的数据集自动标注功能脚本工具【附代码】

近年来&#xff0c;随着深度学习的迅猛发展&#xff0c;计算机视觉领域取得了巨大的突破。其中&#xff0c;目标检测是计算机视觉中的一个重要任务&#xff0c;它在许多应用领域中起到了至关重要的作用。然而&#xff0c;目标检测所需的大量标注数据集的制作却是一项耗时且繁琐…

FlashInternImage实战:使用 FlashInternImage实现图像分类任务(二)

文章目录 训练部分导入项目使用的库设置随机因子设置全局参数图像预处理与增强读取数据设置Loss设置模型设置优化器和学习率调整策略设置混合精度&#xff0c;DP多卡&#xff0c;EMA定义训练和验证函数训练函数验证函数调用训练和验证方法 运行以及结果查看测试完整的代码 在上…

mac配置L2TP连接公司内网

1. 打开系统设置 2. 打开网络 3. 点击网络页面其他服务右下角三个点&#xff0c;添加VPN配置中的L2TP 4. 配置VPN&#xff0c;服务器填写公司的服务器ip&#xff0c;共享密钥没有可以随便填写 5. 打开终端编辑文件 sudo vim /etc/ppp/opt…

Linux系统简介及发展历史

Linux的概况 Linux是自由软件 Linux是一种类UNIX操作系统。Linux内核由Linus Torvalds在1991年发布。在加上用户空间的应用程序之后&#xff0c;成为Linux操作系统 只要遵循GNU通用公共许可证&#xff08;GPL&#xff09;&#xff0c;任何个人和机构都可以自由地使用Linux的所…

网络安全02--负载均衡下的webshell连接

目录 一、环境准备 1.1ubentu虚拟机一台&#xff0c;docker环境&#xff0c;蚁剑 1.2环境压缩包&#xff08;文件已上传资源&#xff09;&#xff1a; 二、开始复原 2.1上传ubentu&#xff1a; 2.2解压缩 2.3版本20没有docker-compose手动下载&#xff0c;包已上传资源 …

Android双指缩放ScaleGestureDetector检测放大因子大图移动到双指中心点ImageView区域中心,Kotlin(2)

Android双指缩放ScaleGestureDetector检测放大因子大图移动到双指中心点ImageView区域中心&#xff0c;Kotlin&#xff08;2&#xff09; 在 Android ScaleGestureDetector检测双指缩放Bitmap基于Matrix动画移动到双指捏合中心点ImageView区域中心&#xff0c;Kotlin-CSDN博客 …

vue+Element UI实现省市区镇四级联动

shigen坚持更新文章的博客写手&#xff0c;擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长&#xff0c;分享认知&#xff0c;留住感动。 在一些需要填写地址的前端页面中&#xff0c;总是少不了需要填写地址的级联选择器&#xff0c;类似这样的&…

【Linux】第三十六站:信号

文章目录 一、信号的概念1.信号概念2.前台与后台进程3.信号的处理4.硬件层面5.信号与我们的代码是异步的 二、信号的产生1.产生的方式2.键盘组合键3.kill命令4.系统调用4.1 kill系统调用4.2 raise4.3 abort 5.异常软件条件5.1 异常产生信号5.2 alarm&#xff08;软件条件产生信…

【Linux】第三十七站:信号保存

文章目录 一、信号发送二、信号保存1.为什么要进行信号保存&#xff1f; 三、阻塞信号1.信号的一些相关概念2.在内核中的表示3.sigset_t4.信号集操作函数5.sigprocmask6.sigpending7. 总结 一、信号发送 如下所示&#xff0c;对于普通信号&#xff0c;它的编号是从1~31。这个是…

N-141基于springboot,vue网上拍卖平台

开发工具&#xff1a;IDEA 服务器&#xff1a;Tomcat9.0&#xff0c; jdk1.8 项目构建&#xff1a;maven 数据库&#xff1a;mysql5.7 系统分前后台&#xff0c;项目采用前后端分离 前端技术&#xff1a;vueelementUI 服务端技术&#xff1a;springbootmybatis-plusredi…

九州金榜|为什么鼓励式家庭教育?

鼓励式教育是一种积极的教育方式&#xff0c;它强调通过鼓励和肯定来激发孩子的积极性和自信心&#xff0c;帮助孩子更好地成长和发展。在家庭教育中&#xff0c;鼓励式教育同样具有重要意义。九州金榜家庭教育和大家一起探讨关于鼓励式教育的好处以及意义&#xff1a; 一.有助…

JRT实体比对

之前已经实现了JRT实体编译的菜单&#xff0c;用Linux指令编译放在网站下的实体代码。那么就有个问题&#xff0c;有人就是直接换实体jar文件不修改网站的实体代码。或者就只修改实体代码不编译搁置在那里&#xff0c;那么后面更新实体的人就得给别人背锅&#xff0c;后面人新编…

机器学习 | 如何使用 Seaborn 提升数据分析效率

Seaborn和Matplotlib都是Python可视化库&#xff0c;它们都可以用于创建各种类型的图表。但是&#xff0c;Seaborn 和Matplotlib在概念和设计上有一些不同。 Matplotlib虽然已经是比较优秀的绘图库了&#xff0c;但是它有个今人头疼的问题&#xff0c;那就是API使用过于复杂&am…
最新文章