美文网首页
自定义TabLayout

自定义TabLayout

作者: dengbin | 来源:发表于2020-03-21 11:14 被阅读0次

    众所周知,TabLayout 特别好用,项目里面需要自定义Tab字体和Indicator

    image

    想到的方案有两个:

    一是获取系统默认TabItem的TextView,然后动态设置字体和背景来实现,后来发现textSize属性不生效,app:tabTextAppearance 满足不了需求。

    二是自定义View,即Tablayout.Tab.setCustomView()。写了demo,实现了需求。整理一下代码重写TabLayout,即插即用,打算后期丰富API,完善过渡动画等。

    import android.content.Context;
    import android.database.DataSetObserver;
    import android.graphics.Typeface;
    import android.support.annotation.NonNull;
    import android.support.annotation.Nullable;
    import android.support.design.widget.TabLayout;
    import android.support.v4.view.PagerAdapter;
    import android.support.v4.view.ViewPager;
    import android.text.TextUtils;
    import android.util.AttributeSet;
    import android.util.TypedValue;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.widget.RelativeLayout;
    import android.widget.TextView;
    
    import com.meishubao.client.R;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @Description: 自定义顶部Tab导航
     * @Author: dengbin
     * @CreateDate: 2020/3/20 18:02
     * @UpdateUser: dengbin
     * @UpdateDate: 2020/3/20 18:02
     * @UpdateRemark: 更新说明
     */
    public class MTabLayout extends TabLayout {
    
        // 所绑定的 ViewPager 的 Adapter
        private PagerAdapter pagerAdapter;
        // title 集合
        private int tmpTitleInitPos;
        private List<CharSequence> titleStringList = new ArrayList<>();
        // 监听 Adapter 数据变化
        private DataSetObserver dataSetObserver = new DataSetObserver() {
            @Override
            public void onChanged() {
                super.onChanged();
                updateTitleText();
            }
    
            @Override
            public void onInvalidated() {
                super.onInvalidated();
                updateTitleText();
            }
        };
        private ViewPager.OnPageChangeListener pageChangeListener = new ViewPager.OnPageChangeListener() {
    
            int currentPos; // 上一次选中的页面
            boolean posChanged; // 页面有所切换
    
            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {
                Tab tab0 = getTabAt(arg0);
                Tab tab1 = getTabAt(arg0 + 1);
                animationTab(tab0, arg1);
                animationTab(tab1, 1f - arg1);
            }
    
            @Override
            public void onPageSelected(int i) {
                posChanged = i != currentPos;
                if (posChanged) {
                    setTabText(getTabAt(currentPos), false);
                    setTabText(getTabAt(i), true);
                }
                currentPos = i;
            }
    
            @Override
            public void onPageScrollStateChanged(int i) {
                if (i != ViewPager.SCROLL_STATE_IDLE || !posChanged)
                    return;
                resetTab(currentPos);
            }
        };
    
        public MTabLayout(Context context) {
            this(context, null);
        }
    
        public MTabLayout(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public MTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
        // 重写该方法,实现 setCustomView
        @NonNull
        @Override
        public Tab newTab() {
            Tab tab = super.newTab();
            View view = LayoutInflater.from(getContext()).inflate(R.layout.item_gallery_tab, null);
            tab.setCustomView(view);
            if (titleStringList.size() > 0 && tmpTitleInitPos < titleStringList.size()) {
                CharSequence cs = titleStringList.get(tmpTitleInitPos++);
                TextView tv = view.findViewById(R.id.tab_tv);
                tv.setText(cs);
            }
    
            if (tmpTitleInitPos == 1) { // 初始化选中第一个
                setTabText(tab, true);
            }
    
            if (tmpTitleInitPos >= titleStringList.size()) {
                titleStringList.clear();
                tmpTitleInitPos = 0;
            }
    
            return tab;
        }
    
        @Override
        public void setupWithViewPager(@Nullable ViewPager viewPager) {
            super.setupWithViewPager(viewPager);
            if (viewPager == null)
                return;
            pagerAdapter = viewPager.getAdapter();
            if (pagerAdapter == null) {
                // 监听 ViewPager 的 Adapter 变化
                viewPager.addOnAdapterChangeListener((viewPager1, pagerAdapter, pagerAdapter1) -> {
                    if (this.pagerAdapter != null)
                        this.pagerAdapter.unregisterDataSetObserver(dataSetObserver);
                    this.pagerAdapter = pagerAdapter1;
                    if (this.pagerAdapter != null)
                        registerDataSetObserver();
                });
            } else {
                registerDataSetObserver();
            }
    
            // 监听 ViewPager 滑动实现过渡效果
            viewPager.addOnPageChangeListener(pageChangeListener);
        }
    
        // 注册数据监听
        private void registerDataSetObserver() {
            pagerAdapter.registerDataSetObserver(dataSetObserver);
        }
    
        // 更新 title 文本,保存到集合
        private void updateTitleText() {
            int adapterCount = pagerAdapter.getCount();
            int curItem;
            for (curItem = 0; curItem < adapterCount; ++curItem) {
                CharSequence title = pagerAdapter.getPageTitle(curItem);
                titleStringList.add(TextUtils.isEmpty(title) ? "" : title);
            }
        }
    
        private void animationTab(Tab tab, float per) {
            if (tab == null || tab.getCustomView() == null)
                return;
            RelativeLayout rl = (RelativeLayout) tab.getCustomView();
            View view = rl.findViewById(R.id.tab_bg_view);
            view.setAlpha(1f - per);
        }
    
        private void setTabText(Tab tab, boolean selected) {
    
            animationTab(tab, selected ? 0f : 1f);
    
            if (tab == null || tab.getCustomView() == null)
                return;
            RelativeLayout rl = (RelativeLayout) tab.getCustomView();
    
            TextView tv = rl.findViewById(R.id.tab_tv);
            tv.setTypeface(Typeface.defaultFromStyle(selected ? Typeface.BOLD : Typeface.NORMAL));
            tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, selected ? 22f : 14f);
            tv.setTextColor(tv.getResources().getColor(selected ? R.color.msb_text_black : R.color.msb_text_gray));
        }
    
        private void resetTab(int currentPos) {
            for (int i = 0; i < getTabCount(); i++)
                setTabText(getTabAt(i), i == currentPos);
        }
    
    }
    

    相关文章

      网友评论

          本文标题:自定义TabLayout

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