VerticalTabLayout 的一些用法

南门新荣
2023-12-01


VerticalTabLayout 是一种纵向的TabLayout,为了满足各种需求被某作者开发出来,怎么开发的暂且不讨论了,先讨论拿来使用,在Android studio gradle文件中添加

添加依赖

compile 'q.rorbin:VerticalTabLayout:1.2.5'

属性说明

xmlcode说明
app:indicator_colorsetIndicatorColor指示器颜色
app:indicator_widthsetIndicatorWidth指示器宽度
app:indicator_gravitysetIndicatorGravity指示器位置
app:indicator_cornerssetIndicatorCorners指示器圆角
app:tab_modesetTabModeTab高度模式
app:tab_heightsetTabHeightTab高度
app:tab_marginsetTabMarginTab间距

VerticalTabLayout 不是继承与Tablayout,而是继承于NestedScrollView,而NestedScrollView继承于Framelayout,所以基本和TableLayout的用法差不多,下面简单介绍几个常用方法

    public void setupWithFragment(FragmentManager manager, List<Fragment> fragments) {
        this.setupWithFragment(manager, 0, fragments);
    }
public void setupWithFragment(FragmentManager manager, int containerResid, List<Fragment> fragments) {
    if (this.mTabFragmentManager != null) {
        this.mTabFragmentManager.detach();
    }

    if (containerResid != 0) {
        this.mTabFragmentManager = new TabFragmentManager(manager, containerResid, fragments, this);
    } else {
        this.mTabFragmentManager = new TabFragmentManager(manager, fragments, this);
    }

}

第一个方法最终调用的也是第二个方法,所以只讲第二个,看参数可以知道这两个方法都是把一些fragment和tab相绑定起来,达到点击tab显示对应fragment的目的,第一个方法没有传入containerResid,所以他会把fragment都加载在tablayout本身身上,需要空出空间来显示fragment,而第一个方法传入了containerResid所以fragment都会显示到传入的view上。

所有参数传入之后先会根据containerResid是否出入构建TabFragmentManager对象,这个对象里会直接把fragment全部加到FragmentTransaction中供切换使用

public void setupWithFragment(FragmentManager manager, List<Fragment> fragments, TabAdapter adapter);
public void setupWithFragment(FragmentManager manager, int containerResid, List<Fragment> fragments, TabAdapter adapter)
public void setupWithFragment(FragmentManager manager, int containerResid, List<Fragment> fragments, TabAdapter adapter) {
        this.setTabAdapter(adapter);
        this.setupWithFragment(manager, containerResid, fragments);
}

这两个方法,看起来好像和上面两个方法也是重载关系,唯一不同的就是这两个方法还多传入了一个参数TabAdapter,这个参数很有用,tab的风格都是由这个adapter决定,其实这两个方法最后都会调用之前的方法,只是比之前多做了一步setTabAdapter,这个方法就是设置TabLayout的方法,可以设置tablayout显示几个,显示成什么样

public void setupWithViewPager(@Nullable ViewPager viewPager);

这个方法就更加厉害了,它是直接把viewpager和tablayout绑定起来,只要将viewpager设置好出入,他就会直接从viewpager中解析数据然后显示出来,看他的代码

public void setupWithViewPager(@Nullable ViewPager viewPager) {
        if (this.mViewPager != null && this.mTabPageChangeListener != null) {    //判断有没添加监听有就移除
            this.mViewPager.removeOnPageChangeListener(this.mTabPageChangeListener);
        }

        if (viewPager != null) {
            PagerAdapter adapter = viewPager.getAdapter();// 获取viewpager的适配器
            if (adapter == null) {
                throw new IllegalArgumentException("ViewPager does not have a PagerAdapter set");
            }

            this.mViewPager = viewPager;
            if (this.mTabPageChangeListener == null) {
                this.mTabPageChangeListener = new VerticalTabLayout.OnTabPageChangeListener();
            }
            // 添加新的监听
            viewPager.addOnPageChangeListener(this.mTabPageChangeListener);
            this.addOnTabSelectedListener(new VerticalTabLayout.OnTabSelectedListener() {
                public void onTabSelected(TabView tab, int position) { //这里基本上就是把viewpager的位置和tab位置相绑定了
                    if (VerticalTabLayout.this.mViewPager != null && VerticalTabLayout.this.mViewPager.getAdapter().getCount() >= position) {
                        VerticalTabLayout.this.mViewPager.setCurrentItem(position);
                    }

                }

                public void onTabReselected(TabView tab, int position) {
                }
            });
            this.setPagerAdapter(adapter, true);// 这个方法中开始会对viewpager监察还有设置tablayout的一些东西
        } else {
            this.mViewPager = null;
            this.setPagerAdapter((PagerAdapter)null, true);
        }

    }

上面的方法最终会走到这里populateFrompageradapter,这个方法很重要,主要是对tablayout的一下设置

private void populateFromPagerAdapter() {
        this.removeAllTabs();
        if (this.mPagerAdapter != null) {
            int adapterCount = this.mPagerAdapter.getCount();
            int curItem;
            if (this.mPagerAdapter instanceof TabAdapter) { // 获取pageradapter是不是实现了TabAdapter借口如果实现了,就直接调用setTabAdapter,负责走默认风格
                this.setTabAdapter((TabAdapter)this.mPagerAdapter);
            } else {
                for(curItem = 0; curItem < adapterCount; ++curItem) {//获取viewpager的title 作为tab的title,然后一个个添加,全部使用默认风格,默认风格无法更改,不太美观
                    String title = this.mPagerAdapter.getPageTitle(curItem) == null ? "tab" + curItem : this.mPagerAdapter.getPageTitle(curItem).toString();
                    this.addTab((new QTabView(this.mContext)).setTitle((new Builder()).setContent(title).build()));
                }
            }

            if (this.mViewPager != null && adapterCount > 0) {
                curItem = this.mViewPager.getCurrentItem();
                if (curItem != this.getSelectedTabPosition() && curItem < this.getTabCount()) {
                    this.setTabSelected(curItem);
                }
            }
        } else {
            this.removeAllTabs();
        }

    }

接下来看看setTabAdapter到底干了啥

public void setTabAdapter(TabAdapter adapter) {
        this.removeAllTabs();
        if (adapter != null) {
            this.mTabAdapter = adapter;

            for(int i = 0; i < adapter.getCount(); ++i) {
                this.addTab((new QTabView(this.mContext)).setIcon(adapter.getIcon(i)).setTitle(adapter.getTitle(i)).setBadge(adapter.getBadge(i)).setBackground(adapter.getBackground(i)));
            }
        }

    }

可以看到,在这个方法里只做了一件事就是添加tab,添加有自定义风格的tab,没错这就是我们想要的,我们的每一个tab不仅可以设置title而且可以设置icon,badge(不知道是是什么鬼),background,这一系列的东西都是我们开发时候想要的,改成自己的风格,接下来看看TabAdapter

public interface TabAdapter {
    int getCount();//个数

    TabBadge getBadge(int var1);

    TabIcon getIcon(int var1);// 图标,传入参数是资源id

    TabTitle getTitle(int var1);//标题

    int getBackground(int var1);//每个一个tab的背景,这里不仅可以用图片还能使用selector,非常好用
}
原来它是一个接口,很有意思了,上面说的viewpager要有自定义风格的话就必须让他的适配器实现这个接口,然后把方法一一实现就能有自定义的风格了,如果有一些参数不能满足自己的审美,我们还可以再改通过获取QTabView这个是每一个tab的view实体,里面有很多的方法可以使用,我们可以通过设置完参数之后再调用 getTabAt(i).getTitleView()
来获取它,然后再自定义一些属性
VerticalTabLayout 确实是个很好用的view,我这里只是简单的介绍了一下,还有很多功能大家可以自行去探索








 类似资料: