Android 组合tablayout+viewpager(tablayout+textview)

我们开发一个app,登陆页进去以后基本都是底部一排4个或者5个tab,上面是和tab数量相同的各自对应的fragment,每开发一个app就要写一次或者你从以前的项目里copy过来,那既然这样,我们自己封装一下,搞一个组合layout会不会省点事……

⚠️注意:我们这里使用的是design包里面的tablayout,在app下build里添加

implementation 'com.android.support:design:27.1.1'

先看下项目结构:

首先我们先看下TabViewPagerLayout:

public class TabViewPagerLayout extends LinearLayout {

}

因为页面上只有两部分,一部分tablayout,另一部分viewpager,所以这个地方我选择继承自LinearLayout,然后设置Orientation为VERTICAL

//初始化
    private void init(Context context) {
        this.setOrientation(LinearLayout.VERTICAL);
        titleList = new ArrayList<>();
        viewList = new ArrayList<>();
        viewPager = new ViewPager(context);
        tabLayout = new TabLayout(context);
    }

接下来就是去初始化tablayout:

前两行代码之所以这么写,是因为当使用addTab()方法给tablayout动态添加文字时可能会出现不显示标题文字的问题,而真实情况并不是不显示文字,而是ViewPager又给TabLayout加了许多空的标题,导致之前手动添加的标题被挤到后面,不信你多往后翻一翻是不是就出来了。那么这些空的标题是如何产生的呢,通过分析TabLayout源码很快就查出这个问题,其中有个方法的代码是这样的:

private void populateFromPagerAdapter() {
        removeAllTabs();

        if (mPagerAdapter != null) {
            final int adapterCount = mPagerAdapter.getCount();
            for (int i = 0; i < adapterCount; i++) {
                    addTab(newTab().setText(mPagerAdapter.getPageTitle(i)), false);
            }

            // Make sure we reflect the currently set ViewPager item
            if (mViewPager != null && adapterCount > 0) {
                final int curItem = mViewPager.getCurrentItem();
                if (curItem != getSelectedTabPosition() && curItem < getTabCount()) {
                    selectTab(getTabAt(curItem));
                }
            }
        } else {
            removeAllTabs();
        }
    }

我们注意看这一行:

for (int i = 0; i < adapterCount; i++) {
                addTab(newTab().setText(mPagerAdapter.getPageTitle(i)), false);
            }

恍然大悟了吧,可以看到在TabLayout里面调用了PageAdapter的方法来添加标题,而添加标题的个数就是在PageAdapter的getCount()方法中设置的,标题的文字是在PageAdapter的getPageTitle()方法中设置。所以我就想:既然它多添加了这么多,那我在它们关联后移除掉所有的tab,然后再添加自己想要的tab不就好了吗,试一试,果然成功了。

tabLayout.setupWithViewPager(viewPager);
tabLayout.removeAllTabs();

for (int i = 0; i < titleList.size(); i++) {
            tabLayout.addTab(tabLayout.newTab().setText(titleList.get(i)));
}

 

/**
     * 初始化TabLayout
     */
    private void initTabLayout() {
        tabLayout.setupWithViewPager(viewPager);
        tabLayout.removeAllTabs();

        //设置高度
        LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, 200);
        tabLayout.setLayoutParams(params);

        //设置tab的模式
        tabLayout.setTabMode(TabLayout.MODE_FIXED);

        //tab的字体选择器,默认黑色,选择时红色
        tabLayout.setTabTextColors(Color.BLACK, Color.RED);

        //tab的下划线颜色,默认是粉红色,如果要自定义选中效果,则可以将下划线设置为和背景色一样.
        tabLayout.setSelectedTabIndicatorColor(Color.RED);

        for (int i = 0; i < titleList.size(); i++) {
            tabLayout.addTab(tabLayout.newTab().setText(titleList.get(i)));
        }

        tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                //将默认位置选中为false
                isSelected(tabLayout.getTabAt(initPosition), false);
                //选中当前位置
                isSelected(tab, true);
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
                //tab未选中
                isSelected(tab, false);
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {
                //tab重新选中
                isSelected(tab, true);
            }
        });

        //进来默认选中位置第0个item
        isSelected(tabLayout.getTabAt(initPosition), true);
    }

    /**
     * 设置选中的tab是否带缩放效果
     *
     * @param tab
     * @param isSelected
     */
    private void isSelected(TabLayout.Tab tab, boolean isSelected) {
        View view = tab.getCustomView();
        if (null != view) {
            view.setScaleX(isSelected ? 1.3f : 1.0f);
            view.setScaleY(isSelected ? 1.3f : 1.0f);
        }
    }

isSelected我设置了如果是传入tav的view是自定义view的时候才会有缩放效果,你也可以取消if(null != view)这层判断,就可以实现任何类型都能缩放。

接下来是初始化viewpager:

/**
     * 初始化ViewPager
     */
    private void initViewP() {
        TabViewPAdapter tabViewPAdapter = new TabViewPAdapter<>(viewList);
        viewPager.setAdapter(tabViewPAdapter);
        if (isNeedAnimation) {
            //添加动画
            switch (animationType) {
                case AnimationType.ZOOM_OUT:
                    transformer = new ZoomOutPageTransformer();
                    break;
                case AnimationType.DEPTH:
                    transformer = new DepthPagerTransformer();
                    break;
            }
            viewPager.setPageTransformer(false, transformer);
        }
    }

初始化viewpager里面设置了是否使用动画,目前只添加了两个,有兴趣的朋友自己可以添加哇,

最后是将tablayout和viewpager都添加到父布局中:

/**
     * 将tablayout和viewpager添加到当前view中
     */
    private void addViews() {
        this.addView(tabLayout);
        this.addView(viewPager);
    }

结束。一个简单的tablayout+viewpager(里面只有textview)的组合就写好了。

这个小组合我已经上传到github,以后会慢慢把其他类型写完整些:

该组合我也上传到jitPack仓库里了,使用方式:在工程build里allprojects添加如下代码:
 

allprojects {
    repositories {
        ...
        maven{url 'https://jitpack.io'}
    }
}

然后在app下的build里添加如下代码:

dependencies {
    ...
    implementation 'com.github.gzy760486540:CustomTabVp:1.0'
}

至此就可以在自己的项目里引用这个小组合了,举个例子:

activity_main:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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"
    tools:context="gzy.customtabvp.MainActivity">

    <gzy.customtabviewpager.view.TabViewPagerLayout
        android:id="@+id/tabViewPagerLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</android.support.constraint.ConstraintLayout>

MainActivity.java:

public class MainActivity extends AppCompatActivity {
    private gzy.customtabviewpager.view.TabViewPagerLayout tabViewPagerLayout;
    private List<String> stringList;
    private List<View> viewList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tabViewPagerLayout = findViewById(R.id.tabViewPagerLayout);

        initData();
        initTab();
    }

    private void initData() {
        stringList = new ArrayList<>();
        viewList = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            stringList.add(String.valueOf(i));
            TextView textView = new TextView(this);
            textView.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
            textView.setHeight(ViewGroup.LayoutParams.MATCH_PARENT);
            textView.setBackgroundColor(getResources().getColor(R.color.colorAccent));
            textView.setText(String.valueOf(i));
            textView.setGravity(Gravity.CENTER);
            textView.setTextColor(Color.parseColor("#FFFFFF"));
            viewList.add(textView);
        }
    }

    private void initTab() {
        tabViewPagerLayout.setTitleList(stringList)
                .setViewList(viewList)
                .isNeedAnimation(true, AnimationType.DEPTH)
                .build();
    }
}

效果如下:

这里只上传一个图片了,上传gif的时候总是报上传失败。

猜你喜欢

转载自blog.csdn.net/qq_27981847/article/details/81133561