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

原创文章,引用请注明出处:http://www.cnblogs.com/baipengzhan/p/6270201.html                      

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属性的详细用法请参考:http://www.cnblogs.com/baipengzhan/p/Android_layout_weight.html                      

 ②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目录需要我们手动创建。颜色状态选择器的代码如下:  

<?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,这一个背景状态选择器,用来改变背景颜色,代码如下:

<?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,是一个普通的状态选择器,用来改变图片,代码如下:

<?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对应的布局:

<?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;

 

代码如下:

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文件中大量的属性可以提取样式,等等,这里列出只是为了方便更多水平的读者读懂,请谅解。

 

好啦,ViewPager + RadioGroup结构我们到此就讲解完成了,感谢阅读!

 

  

  

posted @ 2017-01-14 16:36  chironmy  阅读(2741)  评论(0编辑  收藏  举报