android tablayout 自定义下划线(Indicator)样式 宽度(比文字宽度更短)

通常在ViewPager的上方,我们都会放一个标签指示器与ViewPager进行联动。tablayout作为官方退出的自带控件,大家应该都可以熟练使用了。面对各种需求,tablayout提供了几个简单的方法用来设置颜色,下划线宽度等。下面来完成几个自带方法不能解决的需求:

需求
1:缩短下划线宽度
2:自定义下划线样式,比如弯曲的线条,比tab文字宽度更窄

解决方法
网上有个很好的解决方案,可以用来设置下划线的宽度,是利用反射修改来达到目的:

public 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();  
        }  
    }  

这是可以缩短下划线宽度,但是貌似宽度不能比tab文字宽度更小,但是需求是宽度要比文字还窄。为了可以继续使用tablayout,我们可以自定义一个指示器:

自定义指示器(Indicator)
大致思路:
1:设置tablayout自带指示器高度为0。
2:在tablayout底部放一个自定义的指示器view,比如背景一条横线的窄线条
3:利用tablayout和指示器的宽度计算调整指示器初始位置和第一个tab居中对其
4:监听viewpager的PageChangeListener,根据滑动时候的position和positionOffset动态修改指示器位置,达到滑动效果

代码示例:

tab.post(new Runnable() {
            @Override
            public void run() {
                 initMargin = tab.getWidth() / 4 / 2 - tabIndicator.getWidth() / 2;
                ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) tabIndicator.getLayoutParams();
                params.leftMargin = initMargin;
                tabIndicator.setLayoutParams(params);
            }
        });

获取初始margin值,使指示器和第一个tab居中对齐

tabWidth = tab.getWidth() / 4;
pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

                params.leftMargin = (int) (tabWidth * positionOffset + tabWidth * position)+initMargin;
                tabIndicator.setLayoutParams(params);
            }

            @Override
            public void onPageSelected(int position) {

            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

通过对viewpager的滑动监听动态修改margin值,达到滑动效果就ok了。

你可能感兴趣的:(android开发)