美文网首页Android 学习安卓精华教程Android学习
Android开发:顶部&底部Tab导航栏实现(TabL

Android开发:顶部&底部Tab导航栏实现(TabL

作者: Carson带你学安卓 | 来源:发表于2016-07-24 11:05 被阅读35679次

    前言

    Android开发中使用顶部 & 底部Tab导航栏的频次非常高,主要的实现手段有以下:

    • TabWidget
    • 隐藏TabWidget,使用RadioGroup和RadioButton
    • FragmentTabHost
    • 5.0以后的TabLayout
    • 最近推出的 Bottom navigation

    在上一篇我介绍了如何使用(Fragment+FragmentTabHost++ViewPager)
    实现底部菜单栏,详情请看

    底部Tab菜单栏实现(FragmentTabHost+ViewPager+Fragment)

    今天我手把手教大家如何使用TabLayout+ViewPager+Fragment的组合来实现顶部和底部Tab导航栏,


    目录

    顶部&底部菜单栏.jpg

    1. 概念介绍

    1.1 TabLayout

    • 定义:实现Material Design效果的控件库(Android Design Support Library);
    • 作用:用于实现点击选项进行切换选项卡的自定义效果(5.0可用)

    1.2 ViewPager

    • 定义:ViewPager是android扩展包v4包中的类
    • 作用:左右切换当前的view,实现滑动切换的效果。

    注:
    1.ViewPager类直接继承了ViewGroup类,和LinearLayout等布局一样,都是一个容器,需要在里面添加我们想要显示的内容。
    2.ViewPager类需要PagerAdapter适配器类提供数据,与ListView类似 3.Google官方建议ViewPager配合Fragment使用

    具体使用请参考我写的另外一篇文章:Android开发:ViewPage的介绍

    1.3 Fragment

    • 定义:Fragment是activity的界面中的一部分或一种行为

    1.把Fragment认为模块化的一段activity
    2.它具有自己的生命周期,接收它自己的事件,并可以在activity运行时被添加或删除
    3.Fragment不能独立存在,它必须嵌入到activity中,而且Fragment的生命周期直接受所在的activity的影响。例如:当activity暂停时,它拥有的所有的Fragment们都暂停了,当activity销毁时,它拥有的所有Fragment们都被销毁。

    • 作用:支持更动态、更灵活的界面设计(从3.0开始引入)

    具体使用请参考我写的另外一篇文章Android开发:Fragment介绍&使用方法解析


    2. 总体设计思路

    • TabLayout:点击切换选项卡
    • Fragment:存放不同选项的页面内容
    • ViewPager:实现页面的左右滑动效果

    3. 实现步骤

    利用(TabLayout+ViewPager+Fragment)实现顶部&底部Tab导航栏的步骤一共有6个:

    • 步骤1:添加依赖
    • 步骤2:创建需要的Fragment布局文件(需要多少个Tab选项,就建多少个Fragment)
    • 步骤3:创建Fragment对应的Activity类
    • 步骤4:定义适配器Adapter
    • 步骤5:定义主布局activity_main.xml文件
    • 步骤6:定义MainActivity类

    4. Demo实战

    4.1 效果图(丑是为了让大家更好地理解各个属性设置~~)

    效果图1 效果图2

    4.3 工程目录

    工程目录

    4.3 具体实现

    接下来大家和我一步步去实现吧!!

    强烈建议大家先去Carson_Ho的Github:Top&Bottom_tabbar去下载完整Demo,这样看效果会更好哦!

    步骤1:在Gradle中添加依赖

    //TabLayout
    compile 'com.android.support:support-v4:23.4.0'
    compile 'com.android.support:design:23.4.0'
    //ViewPage
    android.support.v4.view.ViewPager
    

    步骤2:创建需要的Fragment布局文件(需要多少个Tab选项,就建多少个Fragment,这里以4个举例)
    fragment1.xml(一共4个,这里只写出一个)

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="Fragment1"/>
    </RelativeLayout>
    

    步骤3:创建Fragment对应的Activity类
    Fragment1(一共4个,这里只写出一个)

    package com.example.carson_ho.toptabbar;
    
    import android.os.Bundle;
    import android.support.annotation.Nullable;
    import android.support.v4.app.Fragment;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    
    /**
     * Created by Carson_Ho on 16/7/22.
     */
    public class Fragment1 extends Fragment {
    
        @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater,
                                 @Nullable ViewGroup container,
                                 @Nullable Bundle savedInstanceState) {
            return inflater.inflate(R.layout.fragment1, container, false);
        }
    
    }
    
    

    步骤4:定义适配器Adapter类
    这里的适配的作用是将Fragment与ViewPager进行适配
    MyFragmentPagerAdapter.java

    package com.example.carson_ho.toptabbar;
    
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentManager;
    import android.support.v4.app.FragmentPagerAdapter;
    
    /**
     * Created by Carson_Ho on 16/7/22.
     */
    public class MyFragmentPagerAdapter extends FragmentPagerAdapter {
    
        private String[] mTitles = new String[]{"首页", "发现", "进货单","我的"};
    
        public MyFragmentPagerAdapter(FragmentManager fm) {
            super(fm);
        }
    
        @Override
        public Fragment getItem(int position) {
            if (position == 1) {
                return new Fragment2();
            } else if (position == 2) {
                return new Fragment3();
            }else if (position==3){
                return new Fragment4();
            }
            return new Fragment1();
        }
    
        @Override
        public int getCount() {
            return mTitles.length;
        }
    
        //ViewPager与TabLayout绑定后,这里获取到PageTitle就是Tab的Text
        @Override
        public CharSequence getPageTitle(int position) {
            return mTitles[position];
        }
    }
    
    

    步骤5:定义主布局activity_main.xml
    activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <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"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:orientation="vertical"
        tools:context=".MainActivity">
    
        <android.support.design.widget.TabLayout
            android:id="@+id/tabLayout"
            android:layout_width="match_parent"
            android:layout_height="100p"
            //导航栏背景颜色
            android:background="#ffff00"
            //指示器颜色
            app:tabIndicatorColor="#66ff33"
            //指示器高度
            app:tabIndicatorHeight="20p"
            //普通状态下文字的颜色
            app:tabTextColor="@color/colorPrimary"
            //选中时文字的颜色
            app:tabSelectedTextColor="#CC33FF"
            //是否可滑动:fixed:固定;scrollable:可滑动
            app:tabMode="fixed"
            //设置选项卡的背景:此处要写一个selector)
            app:tabBackground="@drawable/selected"
                 //设置字体大小:此处要写一个style) app:tabTextAppearance="@style/MyTabLayoutTextAppearance"/>
        <android.support.v4.view.ViewPager
            android:id="@+id/viewPager"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"/>
    </LinearLayout>
    

    selected.xml

    <selector xmlns:android="http://schemas.android.com/apk/res/android">    <item android:state_selected="true" android:drawable="@color/colorPrimary"/>    <item android:drawable="@color/c1olorAccent"/></selector>
    

    style.xml

    <style name="MyTabLayoutTextAppearance" parent="TextAppearance.AppCompat.Widget.ActionBar.Title">    <item name="android:textSize">5sp</item>    <item name="android:textColor">@color/c1olorAAA</item></style>
    

    步骤6:定义MainActivity
    MainActivity.Java

    package com.example.carson_ho.toptabbar;
    import android.os.Bundle;
    import android.support.design.widget.TabLayout;
    import android.support.v4.view.ViewPager;
    import android.support.v7.app.AppCompatActivity;
    
    public class MainActivity extends AppCompatActivity {
    
        private TabLayout mTabLayout;
        private ViewPager mViewPager;
        private MyFragmentPagerAdapter myFragmentPagerAdapter;
    
        private TabLayout.Tab one;
        private TabLayout.Tab two;
        private TabLayout.Tab three;
        private TabLayout.Tab four;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            getSupportActionBar().hide();//隐藏掉整个ActionBar
            setContentView(R.layout.activity_main);
    
            //初始化视图
            initViews();
        }
        
        private void initViews() {
    
            //使用适配器将ViewPager与Fragment绑定在一起
            mViewPager= (ViewPager) findViewById(R.id.viewPager);
            myFragmentPagerAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager());
            mViewPager.setAdapter(myFragmentPagerAdapter);
    
            //将TabLayout与ViewPager绑定在一起
            mTabLayout = (TabLayout) findViewById(R.id.tabLayout);
            mTabLayout.setupWithViewPager(mViewPager);
    
            //指定Tab的位置
            one = mTabLayout.getTabAt(0);
            two = mTabLayout.getTabAt(1);
            three = mTabLayout.getTabAt(2);
            four = mTabLayout.getTabAt(3);
    
            //设置Tab的图标,假如不需要则把下面的代码删去
            one.setIcon(R.mipmap.ic_launcher);
            two.setIcon(R.mipmap.ic_launcher);
            three.setIcon(R.mipmap.ic_launcher);
            four.setIcon(R.mipmap.ic_launcher);
    
    
        }
    }
    
    

    4.4 效果图(丑是为了让大家更好地理解各个属性设置~~)

    效果图1 效果图2

    4.5 底部Tab导航栏实现

    实现了顶部Tab导航栏,该如何实现底部Tab导航栏实现呢?很简单!只需要在上面步骤5:定义主布局activity_main.xml中将TabLayout和ViewPager的位置交换就可以了!如下图:
    步骤5:定义主布局activity_main.xml
    activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <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"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:orientation="vertical"
        tools:context=".MainActivity">
    
        <android.support.v4.view.ViewPager
            android:id="@+id/viewPager"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"/>
    
        <android.support.design.widget.TabLayout
            android:id="@+id/tabLayout"
            android:layout_width="match_parent"
            android:layout_height="100p"
            //导航栏背景颜色
            android:background="#ffff00"
            //指示器颜色
            app:tabIndicatorColor="#66ff33"
            //指示器高度
            app:tabIndicatorHeight="20p"
            //普通状态下文字的颜色
            app:tabTextColor="@color/colorPrimary"
            //选中时文字的颜色
            app:tabSelectedTextColor="#CC33FF"
            //是否可滑动:fixed:固定;scrollable:可滑动
            app:tabMode="fixed"
            //设置选项卡的背景:此处要写一个selector)
            app:tabBackground="@drawable/selected"/>
    
    </LinearLayout>
    

    效果图

    底部菜单栏效果图

    5. 完整Demo下载地址

    Carson_Ho的Github:Top&Bottom_tabbar


    6. 总结

    本文对利用Google最新的控件库TabLayout实现顶部&底部Tab导航栏进行了全面的讲解,接下来我会继续介绍Android开发中的相关知识,有兴趣可以继续关注Carson_Ho的安卓开发笔记

    请点赞!因为你的鼓励是我写作的最大动力!

    相关文章阅读
    3分钟全面了解Android主流图片加载库
    Handler异步通信机制全面解析(包含Looper、Message Queue)
    Android五大布局介绍&属性设置大全
    Android开发:底部Tab菜单栏实现(FragmentTabHost+ViewPager)
    最全面、最易懂的Android屏幕适配解决方案
    Android开发:5分钟解析Activity&Fragment生命周期
    Android开发:JSON简介及最全面解析方法!
    Android开发:XML简介及DOM、SAX、PULL解析对比


    欢迎关注Carson_Ho的简书!

    不定期分享关于安卓开发的干货,追求短、平、快,但却不缺深度

    相关文章

      网友评论

      • b4edba7f37e0:写的很用心啊
      • ad8336f275cb:怎么在子Fragment布局写事件
      • D13954:100个喜欢
      • 凯撒网络研究院:看了很多你写的文章,第一次评论,。是因为遇到问题了,哈哈,。就是这样实现的话,在其中一个Fragment中有一个button,点击button跳到这四个Fragment之外的第5个Fragment。但是跳过去之后没有数据显示,空白。这是什么原因呢。找了一上午资料了,没有看到相关有用 的答案。
        imurluck:复写FragmentPagerAdapter的destroyItem方法,防止item被销毁,方法里面什么都不写就可以
        凯撒网络研究院:碰到了此类的问题的回复我一下,谢谢了。
      • 59cdbeb4fc8a:当viewpager太多和图片太多的时候 会出现oom,FragmentStatePagerAdapter听说很好 可是我不会用
      • alicemmm:丑cry
      • 你最珍贵only:这个滑块的宽度可以改变吗?
      • 27cf1b7aafea:怎么我加载出来都是最后一个Fragment,打印Log日志三个Fragment都有初始化加载,但是显示出来都是第三个Fragment的内容.......预加载 懒加载有关?
        27cf1b7aafea:@Carson_Ho 我的意思是:订单数据信息都是一样的,只是状态存在不同,我复用一个Fragment就导致数据显示存在问题,分别使用三个Fragment来加载显示数据就是正常的。
        我现在需要处理的是,如何复用Fragment去加载数据在Viewpager进行切换。
        Carson带你学安卓: @变态的疯子 不一定的,可以自己设置数量的。。。
        27cf1b7aafea:Fragment一定要三个吗?
        我的是订单界面,布局都是一样的,就是数据信息的状态不一样而已,完全是可以复用的,所以我就写了一个Fragment界面,尝试分开三个Fragment就不存在该问题。复用一个的时候显示的数据都是最后一个Fragment的数据信息。
      • 松小白:您好,问您一下,底部绿色背景的宽度可以设置么?如果可以的话,能否告诉一下设置办法。研究好长时间了。急急急
        a43242a45bc5:@Carson_Ho 希望能详细说下,看了源码似乎无法直接设置
        Carson带你学安卓:是可以设置的,应该是在Java文件里设置
      • 松小白:您好,问一下底部绿色的如何去掉?
      • 李红祥:答主selcected.xml应该写width和height属性吧
      • 吕檀溪:谷歌出了一个新控件BottomBar可以看看
        Carson带你学安卓:那个坑有点多哈哈
      • 轻舞飞扬儿:博主你好!你写的真是太棒了!学到了很多,但是我有一个问题,就是可不可以在切换fragment的时候不可以手指左右滑动切换,只让点击下部导航进行切换? :smiley:
        30325fdb51da:可以自定义一个不可左右滑动的viewPager替代文中的viewPager
        yangpanRoy:不绑定Viewpager不就行了
      • 数声鹈鹕:学到了很多,非常感谢! 但是我还是要说,demo丑到爆了 :joy:
        Carson带你学安卓:对不起,只是Demo别太在意哈哈
      • keien:图片和文字的间距没办法 设置i,?
        灰咲无但八汪:tab可以设置一个customerview,自定义一个xml文件就行
        a43242a45bc5:@Carson_Ho 可否详细说下?
        Carson带你学安卓:需要在Java文件里实现
      • Lovemyrself:如果fragment.里面还有viewpager .会不会冲突?还有就是底部文字下面的线条 可以不显示吗?
        JingBeibei:@濯伊德 他的意思可以理解为 下面是导航栏 然后在第一个tab里放个banner吧
        JingBeibei:@Lovemyrself 试过了 不会
        3ca6f6426894:@Lovemyrself fragment的是放在底部导航栏上面的,如果你再在fragment里面放viewpager,导航栏只能放在最外层导航栏的上面,这么做很丑的吧

      本文标题:Android开发:顶部&底部Tab导航栏实现(TabL

      本文链接:https://www.haomeiwen.com/subject/vzbijttx.html