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了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章