Android进阶——Material Design新控件之TabLayout制作可滚动的Tabs页面(二)

引言

上一篇总结讲解了下TabLayout的基本特点、属性和简单的应用步骤,相信大家已经对于TabLayout已经不再陌生,这篇就结合Fragment+ViewPager的架构开发一个主流App的主要框架,进一步学习下TabLayout的操作和监听,同时分享一些注意事项和非常见错误的处理方案,系列文章链接:

一、使用TabLayout的项目配置

要使用android.support.design.widget.TabLayout ,需要在自己的工程项目中引入Android的两个库android.support.design.widget.TabLayout在Android扩展(extras)支持(support)包design中,但是design又依赖另外一个support v7包中的appcompat库,因此需要事先导入。Android Studio的添加依赖库很简单,我只需要在我们Module的build.gradle脚本文件中添加如下的(PS:这是使用Android Studio1.4开发的,如果你还使用着Eclipse那么第一步你应该换成Android Studio)

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:support-v4:23.1.1'
    compile 'com.android.support:appcompat-v7:23.1.1'
    compile 'com.android.support:design:23.1.1'
}

二、结合ViewPager+Fragment打造绚丽的Tabs切换页面

1、首先,还是定义MainActivity的主布局和Fragment对应的布局(略)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical">
    <android.support.design.widget.TabLayout
        android:id="@+id/id_tabLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabMode="scrollable"
        app:tabGravity="center"
        />
    <android.support.v4.view.ViewPager
        android:id="@+id/id_viewPager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="#ffffff"
        />
</LinearLayout>

2、然后初始化ViewPagerAdapter和ViewPager

private ViewPagerAdapter mAdapter;
private List<Fragment> mFragments=new ArrayList<Fragment>();
//初始化ViewPagerAdapter
MainFragment mainTab = new MainFragment();
DiscoveryFragment discTab = new DiscoveryFragment();
Tab3Fragment tab3Fragment=new Tab3Fragment();
Tab4Fragment tab4Fragment=new Tab4Fragment();
Tab5Fragment tab5Fragment=new Tab5Fragment();
Tab6Fragment tab6Fragment=new Tab6Fragment();

mFragments.add(mainTab);
mFragments.add(discTab);
mFragments.add(tab3Fragment);
mFragments.add(tab4Fragment);
mFragments.add(tab5Fragment);
mFragments.add(tab6Fragment);
//初始化ViewPager
mAdapter=new ViewPagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mAdapter);

private class ViewPagerAdapter extends FragmentStatePagerAdapter{

        public ViewPagerAdapter(FragmentManager fm) {
            super(fm);
        }
        @Override
        public Fragment getItem(int position) {
            return mFragments.get(position);
        }
        @Override
        public int getCount() {
            return mFragments.size();
        }
        @Override
        public CharSequence getPageTitle(int position) {
            return mTabTitles[position];
        }
    }

3、接着,初始化TabLayout,包括设置一些属性和添加Tab

private static String[] mTabTitles={"Tab1","Tab2","Tab3","Tab4","Tab5","Tab6"};

mTabLayout.setTabMode(TabLayout.MODE_FIXED);
mTabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
mTabLayout.setBackgroundColor(Color.parseColor("#2b2b2b"));
mTabLayout.setTabTextColors(Color.parseColor("#236f28"), Color.parseColor("#bc6e1c"));mTabLayout.addTab(mTabLayout.newTab().setText(mTabTitles[0]));
mTabLayout.addTab(mTabLayout.newTab().setText(mTabTitles[1]));
mTabLayout.addTab(mTabLayout.newTab().setText(mTabTitles[2]));
mTabLayout.addTab(mTabLayout.newTab().setText(mTabTitles[3]));
mTabLayout.addTab(mTabLayout.newTab().setText(mTabTitles[4]));
mTabLayout.addTab(mTabLayout.newTab().setText(mTabTitles[5]));

4、再把ViewPager和TabLayout管理起来

mTabLayout.setupWithViewPager(mViewPager);//mViewPager必须非null

5、再把ViewPager的适配器设置到TabLayout上

mTabLayout.setTabsFromPagerAdapter(mAdapter);

6、设置Tab事件监听

//设置Tab监听
        mTabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                Log.d("TAG","Selected Tab Index为:"+tab.getPosition());
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
                Log.d("TAG","Unselected Tab Index为:"+tab.getPosition());
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {
                Log.d("TAG","Reselected Tab Index为:"+tab.getPosition());
            }
        });

7、完整MainActivity的实现

package com.crazymo.tablayoutviewpager;

import android.graphics.Color;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;


public class MainActivity extends AppCompatActivity {
    private TabLayout mTabLayout;
    private ViewPager mViewPager;
    private ViewPagerAdapter mAdapter;
    private List<Fragment> mFragments = new ArrayList<Fragment>();
    private static String[] mTabTitles = {"Tab1", "Tab2", "Tab3", "Tab4", "Tab5", "Tab6"};

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

    //初始化
    private void init() {
        getView();
        initTab();
    }

    //找到View
    private void getView() {
        mTabLayout = (TabLayout) findViewById(R.id.id_tabLayout);
        mViewPager = (ViewPager) findViewById(R.id.id_viewPager);
    }

    //初始化Tab
    private void initTab() {
        MainFragment mainTab = new MainFragment();
        DiscoveryFragment discTab = new DiscoveryFragment();
        Tab3Fragment tab3Fragment = new Tab3Fragment();
        Tab4Fragment tab4Fragment = new Tab4Fragment();
        Tab5Fragment tab5Fragment = new Tab5Fragment();
        Tab6Fragment tab6Fragment = new Tab6Fragment();

        mFragments.add(mainTab);
        mFragments.add(discTab);
        mFragments.add(tab3Fragment);
        mFragments.add(tab4Fragment);
        mFragments.add(tab5Fragment);
        mFragments.add(tab6Fragment);
        //设置TabLayout的一系列属性
        mTabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
        mTabLayout.setBackgroundColor(Color.parseColor("#2b2b2b"));
        mTabLayout.setTabTextColors(Color.parseColor("#236f28"), Color.parseColor("#bc6e1c"));
        mTabLayout.addTab(mTabLayout.newTab().setText(mTabTitles[0]));
        mTabLayout.addTab(mTabLayout.newTab().setText(mTabTitles[1]));
        mTabLayout.addTab(mTabLayout.newTab().setText(mTabTitles[2]));
        mTabLayout.addTab(mTabLayout.newTab().setText(mTabTitles[3]));
        mTabLayout.addTab(mTabLayout.newTab().setText(mTabTitles[4]));
        mTabLayout.addTab(mTabLayout.newTab().setText(mTabTitles[5]));

        mAdapter = new ViewPagerAdapter(getSupportFragmentManager());
        mViewPager.setAdapter(mAdapter);
        mTabLayout.setupWithViewPager(mViewPager);
        mTabLayout.setTabsFromPagerAdapter(mAdapter);

        //设置Tab监听
        mTabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                Log.e("TAG", "Selected Tab Index为:" + tab.getPosition());
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
                Log.e("TAG", "Unselected Tab Index为:" + tab.getPosition());
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {
                Log.e("TAG", "Reselected Tab Index为:" + tab.getPosition());
            }
        });


    }

    private class ViewPagerAdapter extends FragmentStatePagerAdapter {

        public ViewPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            Log.e("TAG", "获取的Fragement的索引值为:" + position);
            return mFragments.get(position);
        }

        @Override
        public int getCount() {
            return mFragments.size();
        }

        @Override
        public CharSequence getPageTitle(int position) {
            Log.e("TAG", "返回Tab的标题");
            return mTabTitles[position];
        }
    }
}

三、 运行结果

1、初始化进入到主界面时

这里写图片描述
说明ViewPagerAdapter被执行了两次
这里写图片描述

2、 滑动TAB1到TAB2时

仅仅触发的是Tab事件,TAB2到TAB3也是如此。
这里写图片描述

3、 往回滑动TAB3到TAB2时

仅仅触发的是Tab事件,TAB3返回TAB2也是如此。
这里写图片描述
按主页键之后再返回也并未触发任何Tab或者ViewPagerAdapter事件,并且还是返回到原来选中的页面。
这里写图片描述

四、TabLayout的不常见错误及处理方案

1、提示res下某些属性找不到

在导入库过程中,如果某些res目录下的value值过高比如value-23(Android SDK 23)但不巧发生错误如提示说找不到某某值,可以整个删除掉,或者打开SDK下载最新的相关库

2、java.lang.NoClassDefFoundError:android.support.v7.internal.widget.TintManager

发生这个或者类似的,包里的某个类找不到,一般都是因为冲突了,解决办法之一就是,统一使用支持包的版本比如:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:support-v4:23.1.1'
    compile 'com.android.support:appcompat-v7:23.1.1'
    compile 'com.android.support:design:23.1.1'
}

如果还不行就把该工程引入的library moudule的 suppor v4 v7t的版本也改成一致的

3、空指针异常

参照上一篇初始TabLayout的那两个方法的非空声明去排查。

public void setupWithViewPager(@NonNull ViewPager viewPager)	//设置与ViewPager关联起来,注:不允许传递空的ViewPager,否则会异常

public void setTabsFromPagerAdapter(@NonNull PagerAdapter adapter)//设置TabLayout的适配器,注:不允许传递空的PagerAdapter,否则会异常

小结

Android Material Design 滑动指示选项卡TabLayout,就是当用户在该TabLayout的选项卡子item中选择触摸时候,文字和下方的指示器横条滑动指示。最后附上完整demo免费下载

`TabLayout` 是 Android Material Design 中用于创建标签页布局的组件。在 Android Studio 中使用 `com.google.android.material.tabs.TabLayout` 时,可以设置一系列参数来调整其外观和行为。以下是一些常用参数: 1. `app:tabMode`:设置标签页的模式,可以是 `fixed` 或 `scrollable`。`fixed` 模式下所有标签页宽度相同,而 `scrollable` 模式允许标签页根据内容宽度自动调整,超出屏幕宽度的标签页可以通过滚动查看。 2. `app:tabGravity`:设置标签页的对齐方式,可选值有 `fill` 和 `center`。`fill` 值会使得标签页均匀分布填充整个 `TabLayout`,而 `center` 值则会使得标签页居中显示。 3. `app:tabIndicatorColor`:设置标签页指示器的颜色。 4. `app:tabIndicatorHeight`:设置标签页指示器的高度。 5. `app:tabTextAppearance`:设置标签页文本的外观,可以通过引用一个文本样式来改变字体大小、颜色等。 6. `app:tabSelectedTextColor`:设置被选中的标签页文本的颜色。 7. `app:tabTextColor`:设置未被选中的标签页文本的颜色。 8. `app:tabBackground`:设置标签页的背景。 9. `app:tabPaddingStart` 和 `app:tabPaddingEnd`:设置标签页内容的左右内边距。 10. `app:tabMaxWidth`:设置标签页最大宽度。 11. `app:tabMinWidth`:设置标签页最小宽度。 12. `app:tabIndicatorAnimationDuration`:设置标签页指示器动画的持续时间。 13. `app:tabIndicatorFullWidth`:设置标签页指示器是否应该延伸到整个 `TabLayout` 的宽度。 这些参数可以通过 XML 属性设置,也可以在 Java/Kotlin 代码中通过编程方式设置。在 XML 布局文件中使用 `TabLayout` 时,通常是这样的: ```xml <com.google.android.material.tabs.TabLayout android:id="@+id/tabLayout" android:layout_width="match_parent" android:layout_height="wrap_content" app:tabMode="fixed" app:tabGravity="fill" app:tabIndicatorColor="#FF0000" app:tabIndicatorHeight="4dp" app:tabTextAppearance="@style/MyCustomTabText" ... /> ``` 在代码中设置参数,例如: ```java TabLayout tabLayout = findViewById(R.id.tabLayout); tabLayout.setTabMode(TabLayout.MODE_FIXED); tabLayout.setTabGravity(TabLayout.GRAVITY_FILL); tabLayout.setSelectedTabIndicatorColor(Color.RED); tabLayout.setTabIndicatorHeight(4); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CrazyMo_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值