美文网首页实用知识程序员Android技术知识
Tablayout使用全解,一篇就够了

Tablayout使用全解,一篇就够了

作者: 奔跑吧李博 | 来源:发表于2017-12-06 18:05 被阅读6144次

    前言

    Tablayout继承自HorizontalScrollView,用作页面切换指示器,因使用简便功能强大而广泛使用在App中。

    但有的产品经理偏偏是个磨人的小妖精,真的猜不透啊,今天要这种效果,明天就指着另一款App说做成跟这个一样。对付这种产品经理我们有骨气的程序员该怎么办?怎么办?当然是屈服啊,不然去跳楼让他因内疚改需求?
    所以,就在各种复杂的情况下打磨,渐渐地就变得圆润。这里,有Tablayout的各种使用场景,拿去指着产品经理说:你要哪个给你哪个。

    github代码直通车

    先上效果图:分别为设置tab属性、去掉指示线、设置指示线长度、设置图标tab、超出屏幕滚动tab


    使用场景
    常用属性:
    app:tabIndicatorColor :指示线的颜色
    app:tabIndicatorHeight :指示线的高度
    app:tabSelectedTextColor : tab选中时的字体颜色
    app:tabMode="scrollable" : 默认是fixed,固定的;scrollable:可滚动的
    

    各种使用场景:

    1.默认使用样式,结合Viewpager使用:

    效果图:


    giphy.gif

    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"
        tools:context="com.example.tablayoutusecase.defaultuse.MainActivity">
    
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="45dp"
            android:background="@color/colorPrimaryDark">
    
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:text="一般用法"
                android:textColor="#fff"
                android:textSize="16sp"/>
    
        </RelativeLayout>
    
        <android.support.design.widget.TabLayout
            android:id="@+id/tablayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    
    
        <android.support.v4.view.ViewPager
            android:id="@+id/viewpager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    </LinearLayout>
    

    MainActivity使用:根据title长度,设置文字title,设置fragment,设置viewpager联动,使用的是Tablayout默认属性。

    import android.support.design.widget.TabLayout;
    import android.support.v4.app.Fragment;
    import android.support.v4.view.ViewPager;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import com.example.tablayoutusecase.R;
    import java.util.ArrayList;
    
    public class MainActivity extends AppCompatActivity {
        private TabLayout tabLayout;
        private ViewPager viewPager;
        private FmPagerAdapter pagerAdapter;
        private ArrayList<Fragment> fragments = new ArrayList<>();
        private String[] titles = new String[]{"最新","热门","我的"};
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            init();
        }
    
        private void init() {
    
            tabLayout = (TabLayout) findViewById(R.id.tablayout);
            viewPager = (ViewPager) findViewById(R.id.viewpager);
    
            for(int i=0;i<titles.length;i++){
                fragments.add(new TabFragment());
                tabLayout.addTab(tabLayout.newTab());
            }
    
            tabLayout.setupWithViewPager(viewPager,false);
            pagerAdapter = new FmPagerAdapter(fragments,getSupportFragmentManager());
            viewPager.setAdapter(pagerAdapter);
    
            for(int i=0;i<titles.length;i++){
                tabLayout.getTabAt(i).setText(titles[i]);
            }
        }
    
    }
    
    2.设置Tablayout属性:

    效果图:


    image.png

    用Tablayout属性写一个style,给需要的Tablayout引用。

        <style name="MyTablayoutstyle" parent="Base.Widget.Design.TabLayout">
            <item name="tabBackground">@color/white</item>
            <item name="tabIndicatorColor">@color/green</item>
            <item name="tabIndicatorHeight">2dp</item>
            <item name="tabSelectedTextColor">@color/green</item>
            <item name="android:textSize">15sp</item>
            <item name="android:textColor">@color/text</item>
        </style>
    

    Tablayout引用:

        <android.support.design.widget.TabLayout
            android:id="@+id/tab1"
            style="@style/MyTablayoutstyle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    
    3.Tablayout去掉指示线:
    image.png

    这种很easy,给tabIndicatorHeight属性设置0dp,或者给tabSelectedTextColor属性设置透明,就不显示指示线了。

    4.修改指示线长度:
    image.png

    怎么办呢,在布局里怎么打也打不出来这个所谓的”tabIndicatorWidth“属性,那就点进去Tablayout类里面找,看它是怎么实现指示线的。

    找到有如下属性,即有SlidingTabStrip内部类:

        private final SlidingTabStrip mTabStrip;
    
    image.png

    通过阅读发现该类就是设置指示线的,继承于Linearylayout。那么我们可以通过反射获取Tablayout的mTabStrip,循环获取到子view,设置leftMargin,rightMargin就可以压缩tab的宽度了。

    一不做二不休,IndicatorLineUtil实现类:

    import android.content.res.Resources;
    import android.support.design.widget.TabLayout;
    import android.util.TypedValue;
    import android.view.View;
    import android.widget.LinearLayout;
    import java.lang.reflect.Field;
    
    public class IndicatorLineUtil {
        /**
         * 调节tablayout指示线宽度
         * @param tabs
         * @param leftDip
         * @param rightDip
         */
        public static void setIndicator(TabLayout tabs, int leftDip, int rightDip) {
            Class<?> tabLayout = tabs.getClass();
            Field tabStrip = null;
            try {
                tabStrip = tabLayout.getDeclaredField("mTabStrip");
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            }
    
            tabStrip.setAccessible(true);
            LinearLayout llTab = null;
            try {
                llTab = (LinearLayout) tabStrip.get(tabs);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
    
            int left = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, leftDip, Resources.getSystem().getDisplayMetrics());
            int right = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, rightDip, Resources.getSystem().getDisplayMetrics());
    
            for (int i = 0; i < llTab.getChildCount(); i++) {
                View child = llTab.getChildAt(i);
                child.setPadding(0, 0, 0, 0);
                LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1);
                params.leftMargin = left;
                params.rightMargin = right;
                child.setLayoutParams(params);
                child.invalidate();
            }
    
    
        }
    }
    

    tablayout调用此方法:注意:margin数值不能设置过大,不然tab宽度压缩为0整个tablayout就不显示了。

            tab3.post(new Runnable() {
                @Override
                public void run() {
                    IndicatorLineUtil.setIndicator(tab3, 40, 40);
                }
            });
    
    5.设置默认图标:
    image.png

    still easy,Tablayout自带了setIcon()方法设置图标资源,不过这中效果很别扭,脸被拉长了。不服,就自己造一个啊,造就造!
    tabLayout.getTabAt(i).setText(titles[i]).setIcon(pics[i]);

    6.自己造tab样式:
    image.png

    创建图标和文字布局:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="horizontal"
        android:layout_width="wrap_content"
        android:layout_height="48dp"
        android:gravity="center">
    
        <ImageView
            android:id="@+id/imageview"
            android:layout_gravity="center"
            android:layout_width="24dp"
            android:layout_height="24dp" />
    
        <TextView
            android:id="@+id/textview"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center"
            android:textSize="14sp"
            android:layout_marginLeft="8dp"/>
    </LinearLayout>
    

    这里是图标居左,那我要改为图标上下左右呢?都自定义view了,你上天都行。

        /**
         * 设置自定义位置图标
         */
        private void setCustomIcon() {
    
            tabLayout2 = (TabLayout) findViewById(R.id.tablayout2);
            for(int i=0;i<titles.length;i++){
                tabLayout2.addTab(tabLayout2.newTab());
            }
    
            for(int i=0;i<titles.length;i++){
                tabLayout2.getTabAt(i).setCustomView(makeTabView(i));
            }
        }
    
        /**
         * 引入布局设置图标和标题
         * @param position
         * @return
         */
        private View makeTabView(int position){
            View tabView = LayoutInflater.from(this).inflate(R.layout.tab_text_icon,null);
            TextView textView = tabView.findViewById(R.id.textview);
            ImageView imageView = tabView.findViewById(R.id.imageview);
            textView.setText(titles[position]);
            imageView.setImageResource(pics[position]);
    
            return tabView;
        }
    
    7.tab数量太多,超出屏幕,就像今日头条的分类一样,那就挤在一起了啊。不怕,我们有app:tabMode="scrollable" 属性,让Tablayout变得可滚动,可超出屏幕。
    image.png

    布局引入:

        <android.support.design.widget.TabLayout
            android:id="@+id/tablayout3"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:tabSelectedTextColor="@color/green"
            android:layout_marginTop="20dp"
            app:tabMode="scrollable"
            android:background="@color/white"/>
    
    最后大合唱完整Activity:
    import android.support.design.widget.TabLayout;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.widget.ImageView;
    import android.widget.TextView;
    import com.example.tablayoutusecase.R;
    
    public class SetStyleActivity extends AppCompatActivity {
        private TabLayout tab1,tab2,tab3;
        private TabLayout tabLayout,tabLayout2,tabLayout3;
        private String[] titles = new String[]{"最新","热门","我的"};
        private String[] longTitles = new String[]{"推荐","热点","北京","视频","社会","图片","娱乐","科技","汽车"};
        private int[] pics = new int[]{R.mipmap.subtitle_left_roll_h,R.mipmap.subtitle_middle_roll_h,R.mipmap.subtitle_right_roll_h};
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_usecase);
    
            setTab1();
            setTab2();
            setTab3();
            setDefaultIcon();
            setCustomIcon();
            setScroll();
        }
    
        private void setTab1(){
            tab1 = (TabLayout) findViewById(R.id.tab1);
            for(int i=0;i<titles.length;i++){
                tab1.addTab(tab1.newTab());
                tab1.getTabAt(i).setText(titles[i]);
            }
        }
    
        private void setTab2(){
            tab2 = (TabLayout) findViewById(R.id.tab2);
            for(int i=0;i<titles.length;i++){
                tab2.addTab(tab2.newTab());
                tab2.getTabAt(i).setText(titles[i]);
            }
        }
    
        private void setTab3(){
            tab3 = (TabLayout) findViewById(R.id.tab3);
            for(int i=0;i<titles.length;i++){
                tab3.addTab(tab3.newTab());
                tab3.getTabAt(i).setText(titles[i]);
            }
    
            tab3.post(new Runnable() {
                @Override
                public void run() {
                    IndicatorLineUtil.setIndicator(tab3, 40, 40);
                }
            });
        }
    
        /**
         * 设置默认图标
         */
        private void setDefaultIcon() {
    
            tabLayout = (TabLayout) findViewById(R.id.tablayout);
            for(int i=0;i<titles.length;i++){
                tabLayout.addTab(tabLayout.newTab());
            }
    
            for(int i=0;i<titles.length;i++){
                tabLayout.getTabAt(i).setText(titles[i]).setIcon(pics[i]);
            }
        }
    
        /**
         * 设置自定义位置图标
         */
        private void setCustomIcon() {
    
            tabLayout2 = (TabLayout) findViewById(R.id.tablayout2);
            for(int i=0;i<titles.length;i++){
                tabLayout2.addTab(tabLayout2.newTab());
            }
    
            for(int i=0;i<titles.length;i++){
                tabLayout2.getTabAt(i).setCustomView(makeTabView(i));
            }
        }
    
        private void setScroll(){
            tabLayout3 = (TabLayout) findViewById(R.id.tablayout3);
            for(int i=0;i<longTitles.length;i++){
                tabLayout3.addTab(tabLayout3.newTab());
            }
    
            for(int i=0;i<longTitles.length;i++){
                tabLayout3.getTabAt(i).setText(longTitles[i]);
            }
        }
    
        /**
         * 引入布局设置图标和标题
         * @param position
         * @return
         */
        private View makeTabView(int position){
            View tabView = LayoutInflater.from(this).inflate(R.layout.tab_text_icon,null);
            TextView textView = tabView.findViewById(R.id.textview);
            ImageView imageView = tabView.findViewById(R.id.imageview);
            textView.setText(titles[position]);
            imageView.setImageResource(pics[position]);
    
            return tabView;
        }
    
    }
    

    我明明是个程序员,却怎么要老是做图,蓝瘦香菇。
    好了,Tablayout各种使用场景就讲解完了,代码在顶端。觉得有用的话关注我一起学习吧。

    相关文章

      网友评论

        本文标题:Tablayout使用全解,一篇就够了

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