zoukankan      html  css  js  c++  java
  • 【Tab导航】ViewPager+RadioButton轻松实现底部Tab导航

    一、概述

     实现类似微信哪种底部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下载

  • 相关阅读:
    Dynamics CRM安装教程一:域环境准备
    C#判断日期是否合法
    Visual Studio 2015 无法加载.Net FrameWork4.6.2
    Dynamics CRM产生公共签名,避免每次插件换环境重新输入签名密钥账号密码
    Dynamics CRM使用JS隐藏自定义按钮
    <3>Python开发——列表(list)
    <2>Python开发——字符串(str)
    <1>Python开发——基础入门
    Sed命令详解
    国内搭建Minikube测试环境
  • 原文地址:https://www.cnblogs.com/ydxlt/p/5034536.html
Copyright © 2011-2022 走看看