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];
        }
    }
}

运行结果

初始化进入到主界面时

说明ViewPagerAdapter被执行了两次

滑动TAB1到TAB2时

仅仅触发的是Tab事件,TAB2到TAB3也是如此。

往回滑动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免费下载

时间: 2024-12-30 10:54:48

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

Android进阶——Material Design新控件之初识TabLayout(一)

引言 Google I/O 2015 推出的 Android Design Support Library令人非常激动.Material Design的推出确实振奋了不少 Android开发者以及用户的心.以前Google给我的感觉就像是他并没太在乎他们的UI(或者审美不同,Gmail不忍吐槽),但是当Material Design伴随Android5.0发布之后,一切好像就都变了个样,Google好像意识到了设计的重要性以及自己以往的种种不足,决定也要迎头赶上,不仅仅只是推出一套Materia

Android Design新控件之TextInputLayout(文本输入布局)

谷歌在推出Android5.0的同时推出了全新的设计Material Design,谷歌为了给我们提供更加规范的MD设计风格的控件,在2015年IO大会上推出了Design支持包,Design常用的新控件包括: TextInputLayout(文本输入布局) TabLaout(选项卡布局) Snackbar FloatingActionButton(浮动按钮) NavigationView(导航视图) AppBarLayout(程序栏布局) CoordinatorLayout(协作布局) Col

MaterialEditText——Android Material Design EditText控件

MaterialEditText是Android Material Design EditText控件.可以定制浮动标签.主要颜色.默认的错误颜色等. 随着 Material Design 的到来, AppCompat v21 中也提供了 Material Design 的控件外观支持,其中包括 EditText .但 AppCompat 中的 EditText 实在有点难用,因为它是通过 colorAccent 来自动为控件着色的,并没有提供设置颜色的api,因此需要通过为控件定制theme的

一个Activity掌握Design新控件

一个Activity掌握Design新控件 欢迎转载,转载请注明原文地址:http://blog.csdn.net/lavor_zl/article/details/51295364谢谢. 谷歌在推出Android5.0的同时推出了全新的设计Material Design,谷歌为了给我们提供更加规范的MD设计风格的控件,在2015年IO大会上推出了Design支持包,Design常用的新控件有下面8种. 1. TextInputLayout(文本输入布局) TextInputLayout的作用是

Android控件使用 — 12个Material Design风格控件的使用

项目在GitHub上的地址: https://github.com/Hebin320/MaterialDesignUse 1.AppBarLayout.ToolBar AppBarLayout 是继承LinerLayout实现的一个ViewGroup容器组件,它是为了Material Design设计的App Bar,支持手势滑动操作. AppBarLayout必须作为Toolbar的父布局容器,也可以配合CoordinatorLayout一起使用. ToolBar是谷歌新推出的代替Action

Android Material Design新UI控件使用大全 一

序言 自从谷歌在2014年的IO大会上推出了Material Design新的设计规范后,安卓应用的整体美观程度提升了很大的一个层次, 安卓再也不是又黑又丑的界面,取而代之的是拥有丰富的颜色,美观的按钮,好的用户体验;但是刚开始的话这种设计规范只能在Android 5.0以上的手机上运行,导致开发者也只是自己去体验,在国内并没有大范围的推广,App的质量并不能大幅度的提升,但是作为改变世界的Google公司不久就推出了兼容库Android Material Design,这绝对是业界良心了,我们

ANDROID L——Material Design详解(UI控件)

转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! Android L: Google已经确认Android L就是Android Lollipop(5.0). 前几天发现Android5.0正式版的sdk已经可以下载了,而且首次搭载Android L系统的Nexus 6和 Nexus 9也即将上市. 所以是时候开始学习Android L了! 关于Android L如何配置模拟器和创建项目,如果大家有兴趣的话可以看看我之前的一篇文章: A

Android M新控件之AppBarLayout,NavigationView,CoordinatorLayout,CollapsingToolbarLayout的使用

[转载请注明出处:http://blog.csdn.net/feiduclear_up/article/details/46514791 CSDN 废墟的树] 上一篇博客我们学习了Android Design Support Library库中的 是个简单的组件,不了解的童鞋可以参考之前的博客 Android M新控件之FloatingActionButton,TextInputLayout,Snackbar,TabLayout的使用. 这篇博客我们继续学习Design库中的其他四个组件,分别是

【转】Android M新控件之FloatingActionButton,TextInputLayout,Snackbar,TabLayout的使用

Android M新控件之FloatingActionButton,TextInputLayout,Snackbar,TabLayout的使用 分类: Android UI2015-06-15 16:44 1145人阅读 评论(5) 收藏 举报 MaterialDesingsupportlibrary 目录(?)[-] 前提 FloatingActionButton TextInputLayout Snackbar的使用 TabLayout [转载请注明出处:http://blog.csdn.n