文章大纲
- 引言
- 一、使用TabLayout的项目配置
- 二、结合ViewPager+Fragment打造绚丽的Tabs切换页面
- 1、首先,还是定义MainActivity的主布局和Fragment对应的布局(略)
- 2、然后初始化ViewPagerAdapter和ViewPager
- 3、接着,初始化TabLayout,包括设置一些属性和添加Tab
- 4、**再把ViewPager和TabLayout管理起来**
- 5、再把ViewPager的适配器设置到TabLayout上
- 6、设置Tab事件监听
- 7、完整MainActivity的实现
- 三、 运行结果
- 1、初始化进入到主界面时
- 2、 滑动TAB1到TAB2时
- 3、 往回滑动TAB3到TAB2时
- 四、TabLayout的不常见错误及处理方案
- 1、提示res下某些属性找不到
- 2、java.lang.NoClassDefFoundError:android.support.v7.internal.widget.TintManager
- 3、空指针异常
- 小结
引言
上一篇总结讲解了下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中选择触摸时候,文字和下方的指示器横条滑动指示。