ViewPager+RadioButton轻松实现底部Tab导航

来源:互联网 发布:澳洲硕士知乎 编辑:程序博客网 时间:2024/05/04 13:02

一、概述

 实现类似微信哪种底部tab导航的方式有很多种,这篇文章先介绍实现这种底部导航的一种简单的方式,即ViewPager+RedioButton实现底部tab导航。

实现之前,我们先看一下即将要实现的导航效果图:

这里写图片描述

OK,下面我们通过代码一步一步实现上图的底部导航效果。

二、编写代码

第一步:编写主界面的布局,activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical" >    <android.support.v4.view.ViewPager        android:id="@+id/viewPager"        android:layout_width="match_parent"        android:layout_height="0dp"        android:layout_weight="1" >    </android.support.v4.view.ViewPager>    <View        android:layout_width="match_parent"        android:layout_height="1dp"        android:background="@color/devider_line" >    </View>    <RadioGroup        android:id="@+id/radioGroup"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="horizontal"        android:padding="10dp" >        <RadioButton            android:id="@+id/btn_home"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:background="@null"            android:button="@null"            android:drawablePadding="3dp"            android:drawableTop="@drawable/ic_tab_home_yellow"            android:gravity="center_horizontal"            android:text="@string/tab_home"            android:textColor="@color/yellow" />        <RadioButton            android:id="@+id/btn_classify"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:background="@null"            android:button="@null"            android:drawablePadding="3dp"            android:drawableTop="@drawable/ic_tab_classify_yellow"            android:gravity="center_horizontal"            android:text="@string/tab_classify"            android:textColor="@color/yellow" />        <RadioButton            android:id="@+id/btn_discover"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:background="@null"            android:button="@null"            android:drawablePadding="3dp"            android:drawableTop="@drawable/ic_tab_discover_yellow"            android:gravity="center_horizontal"            android:text="@string/tab_discover"            android:textColor="@color/yellow" />        <RadioButton            android:id="@+id/btn_me"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:layout_weight="1"            android:background="@null"            android:button="@null"            android:drawablePadding="3dp"            android:drawableTop="@drawable/ic_tab_me_yellow"            android:gravity="center_horizontal"            android:text="@string/tab_me"            android:textColor="@color/yellow" />    </RadioGroup></LinearLayout>

 注意:

  • RadioButton默认是前面带有圆点的,去掉前面圆点的方法:
    将button属性设为null,即:
 android:button="@null"
  • 让RadioButton的文本水平居中,即:
android:gravity="center_horizontal"
  • 可以添加一个宽度为屏幕填充父容器,高度为0.1dp的View,设置颜色背景实现分割线的效果

  • 当设置了view的weight属性后,可以将宽度或者高度设为0dp,这样可以提高效率

第二步:MainActivity处理逻辑

1、初始化Fragment

protected void init() {        Fragment homeFragment = new HomeFragment();        Fragment classifyFragment = new ClassifyFragment();        Fragment discoverFragment = new DiscoverFragment();        Fragment meFragment = new MeFragment();        fragments.add(homeFragment);        fragments.add(classifyFragment);        fragments.add(discoverFragment);        fragments.add(meFragment);    }
  • fragments为一个盛放Fragment的List集合
  • 其中的一个Fragment的代码(其他的一样,只是显示的文本不同):
package com.lt.bottomtabdemo.fragment;import android.os.Bundle;import android.support.v4.app.Fragment;import android.view.Gravity;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.view.ViewGroup.LayoutParams;import android.widget.TextView;/** * Created by lt on 2015/12/1. */public class HomeFragment extends Fragment{    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container,            Bundle savedInstanceState) {        TextView textView = new TextView(getActivity());        LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);        textView.setGravity(Gravity.CENTER);        textView.setLayoutParams(params);        textView.setText("首页");        return textView;    }}

2、初始化View并为ViewPager设置Adapter

mRadioGroup = (RadioGroup) findViewById(R.id.radioGroup);mViewPager = (ViewPager) findViewById(R.id.viewPager);TabPageAdapter tabPageAdapter = new TabPageAdapter(            getSupportFragmentManager(), fragments);mViewPager.setAdapter(tabPageAdapter);mViewPager.setOnPageChangeListener(this);

其中 TagPagerAdapter.java

package com.lt.bottomtabdemo.adapter;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentManager;import android.support.v4.app.FragmentPagerAdapter;import android.view.ViewGroup;import java.util.List;/** * Created by lt on 2015/12/1. * app导航内容区域适配器 */public class TabPageAdapter extends FragmentPagerAdapter{    private List<Fragment> fragments;    public TabPageAdapter(FragmentManager fm,List<Fragment> fragments) {        super(fm);        this.fragments = fragments;    }    @Override    public Fragment getItem(int position) {        return fragments.get(position);    }    @Override    public int getCount() {        return fragments.size();    }    /**     * 重写,不让Fragment销毁     */    @Override    public void destroyItem(ViewGroup container, int position, Object object) {    }}

这里重写destroyItem什么都不做,这里只有四个页面没必要让系统销毁Fragment。

3、写一个切换页面的方法:

/**     * 选择某页     * @param position 页面的位置     */    private void selectPage(int position) {        // 将所有的tab的icon变成灰色的        for (int i = 0; i < mRadioGroup.getChildCount(); i++) {            Drawable gray = getResources().getDrawable(unselectedIconIds[i]);            // 不能少,少了不会显示图片            gray.setBounds(0, 0, gray.getMinimumWidth(),                    gray.getMinimumHeight());            RadioButton child = (RadioButton) mRadioGroup.getChildAt(i);            child.setCompoundDrawables(null, gray, null, null);            child.setTextColor(getResources().getColor(                    R.color.dark_gray));        }        // 切换页面        mViewPager.setCurrentItem(position, false);        // 改变图标        Drawable yellow = getResources().getDrawable(selectedIconIds[position]);        yellow.setBounds(0, 0, yellow.getMinimumWidth(),                yellow.getMinimumHeight());        RadioButton select = (RadioButton) mRadioGroup.getChildAt(position);        select.setCompoundDrawables(null, yellow, null, null);        select.setTextColor(getResources().getColor(                R.color.yellow));    }

 用到的数组资源,分别是按钮选中与没有选中状态显示的图片资源:

/**     * 按钮的没选中显示的图标     */    private int[] unselectedIconIds = { R.drawable.ic_tab_home_gray,            R.drawable.ic_tab_classify_gray, R.drawable.ic_tab_discover_gray,            R.drawable.ic_tab_me_gray };    /**     * 按钮的选中显示的图标     */    private int[] selectedIconIds = { R.drawable.ic_tab_home_yellow,            R.drawable.ic_tab_classify_yellow, R.drawable.ic_tab_discover_yellow,            R.drawable.ic_tab_me_yellow };

 selectPage(int postion)方法说明:

  • 遍历RadioGroup将所有的RadioButton的上面的图片和文本颜色设为没有选中的状态:

    • 通过RadioButton.setCompoundDrawables(left, top, right, bottom);变换RadioButton的四个方向的图片,这里我们要换掉上面的图片,所以先得到上面的图片Drawable对象(注意要设置图片显示的大小):
            Drawable gray = getResources().getDrawable(unselectedIconIds[i]);            // 不能少,少了不会显示图片,设置显示的范围,为一个矩形            gray.setBounds(0, 0, gray.getMinimumWidth(),                    gray.getMinimumHeight());
  • 然后在设置选中的那个RadioButton上面的图片和文本颜色

这里的position是指当前页面对应的tab按钮RadioButton在RadioGroup中的排序。

4、为了底部RadioButton点击后可以切换到相应的页面,为RadioGroup设置按钮选中改变的监听:

mRadioGroup.setOnCheckedChangeListener(this);

 实现onCheckedChanged方法

@Override    public void onCheckedChanged(RadioGroup group, int checkedId) {        switch (checkedId) {            case R.id.btn_home: // 首页选中                selectPage(0);                break;            case R.id.btn_classify: // 分类选中                selectPage(1);                break;            case R.id.btn_discover: // 发现选中                selectPage(2);                break;            case R.id.btn_me: // 个人中心选中                selectPage(3);                break;        }    }

5、为了让ViewPager滑动的同时改变底部按钮选择状态,为ViewPager设置页面改变监听:

mViewPager.setOnPageChangeListener(this);

 实现接口的三个方法(只实现其中的onPageSelected,其它的给空实现):

@Override    public void onPageSelected(int position) {        selectPage(position);    }

OK,到这里我们 ViewPager+RadioButton 实现底部导航的例子完成了。

总结:ViewPager+RadioButton这种方式轻松实现底部导航。

Demo下载

0 0
原创粉丝点击