Tab标签切换页面的多种实现方式

时间:2022-11-18 23:49:18

Tab标签切换页面在APP界面中十分常见,可分为底部标签和顶部标签,进一步又分为可滑动不可滑动(主要在于是否使用了support v4包下的ViewPager)。不可滑动的界面通过点击Tab标签所在的View来实现页面的切换;可滑动的界面还可通过屏幕的左右滑动来切换页面。以下介绍Tab标签切换页面的5种实现方式:


Tab实现方案一:

仅使用ViewPager(外加PagerAdapter,确保可以滑动切换页面)


实现原理较为简单:通过调用viewPager的addOnPageChangeListener方法进行滑动切换页面,

同时调用Tab标签所在的父布局LinearLayout的setOnClickListener方法实现点击切换页面。


主要步骤如下:


布局文件


activity_tab1,xml

<?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"
android:orientation="vertical">

<include layout="@layout/title_tab1" />

<android.support.v4.view.ViewPager
android:id="@+id/viewPager_tab1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>

<include layout="@layout/bottom_tab1" />

</LinearLayout>


注:布局文件中包含了可复用的title_bar1.xml和bottom_tab1.xml


title_bar1.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:background="@color/colorPrimary"
android:gravity="center_horizontal"
android:layout_height="wrap_content">

<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/app_name"
android:layout_margin="10dp"
android:src="@mipmap/zhidao_logo"/>

</LinearLayout>


bottom_tab1.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:baselineAligned="false"
android:background="@color/colorPrimary"
android:layout_height="wrap_content">

<LinearLayout
android:id="@+id/ll_tab1_know"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_horizontal"
android:orientation="vertical">

<!-- 默认ImageButton可点击,ImageView不可点击
这里clickable设置为false,把点击事件交给外层的父布局处理
优化点击效果-->
<!-- background设置为透明,去除ImageButton自带的灰色背景 -->
<ImageButton
android:id="@+id/ib_know"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:src="@mipmap/btn_know_pre"
android:background="#00000000"
android:clickable="false"
android:contentDescription="@string/app_name"/>
<TextView
android:id="@+id/tv_know"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_marginTop="10dp"
android:layout_marginBottom="5dp"
android:textColor="@color/colorPressed"
android:text="知道"/>
</LinearLayout>
<LinearLayout
android:id="@+id/ll_tab1_want_to_know"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_horizontal"
android:orientation="vertical">

<ImageButton
android:id="@+id/ib_want_to_know"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:src="@mipmap/btn_wantknow_nor"
android:background="#00000000"
android:clickable="false"
android:contentDescription="@string/app_name"/>
<TextView
android:id="@+id/tv_want_to_know"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_marginTop="10dp"
android:layout_marginBottom="5dp"
android:textColor="@color/colorNormal"
android:text="我想知道"/>
</LinearLayout>
<LinearLayout
android:id="@+id/ll_tab1_my_pager"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_horizontal"
android:orientation="vertical">

<ImageButton
android:id="@+id/ib_my_pager"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:src="@mipmap/btn_my_nor"
android:background="#00000000"
android:clickable="false"
android:contentDescription="@string/app_name"/>
<TextView
android:id="@+id/tv_my_page"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_marginTop="10dp"
android:layout_marginBottom="5dp"
android:textColor="@color/colorNormal"
android:text="我的主页"/>
</LinearLayout>

</LinearLayout>


view1_tab1.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:gravity="center"
android:layout_height="match_parent">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="知道"/>

</LinearLayout>


注:view2_tab2.xml和view3_tab3.xml同理


Java代码:


TabActivity.java

package me.hlq.tabdemo;

import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;

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

/**
* Tab实现方案一:
* 仅使用ViewPager(外加PagerAdapter,确保可以滑动切换页面)
*
* @author HLQ 2016/10/23
*/

public class TabActivity1 extends AppCompatActivity implements View.OnClickListener{

private LinearLayout ll_tab1_know;
private LinearLayout ll_tab1_want_to_know;
private LinearLayout ll_tab1_my_pager;

private ImageButton ib_know;
private ImageButton ib_want_to_know;
private ImageButton ib_my_pager;
private TextView tv_know;
private TextView tv_want_to_know;
private TextView tv_my_page;

private ViewPager viewPager_tab1;

private List<View> viewList = new ArrayList<>();

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

initView();
setListener();
}

private void setListener() {

ll_tab1_know.setOnClickListener(this);
ll_tab1_want_to_know.setOnClickListener(this);
ll_tab1_my_pager.setOnClickListener(this);
}

private void initView() {

ll_tab1_know = (LinearLayout) findViewById(R.id.ll_tab1_know);
ll_tab1_want_to_know = (LinearLayout) findViewById(R.id.ll_tab1_want_to_know);
ll_tab1_my_pager = (LinearLayout) findViewById(R.id.ll_tab1_my_pager);
ib_know = (ImageButton) findViewById(R.id.ib_know);
ib_want_to_know = (ImageButton) findViewById(R.id.ib_want_to_know);
ib_my_pager = (ImageButton) findViewById(R.id.ib_my_pager);
tv_know = (TextView) findViewById(R.id.tv_know);
tv_want_to_know = (TextView) findViewById(R.id.tv_want_to_know);
tv_my_page = (TextView) findViewById(R.id.tv_my_page);

viewPager_tab1 = (ViewPager) findViewById(R.id.viewPager_tab1);

initList();

viewPager_tab1.setAdapter(new PagerAdapter() {
@Override
public int getCount() {
return viewList.size();
}

@Override
public boolean isViewFromObject(View view, Object object) {
return view==object;
}

@Override
public Object instantiateItem(ViewGroup container, int position) {

View view = viewList.get(position);
container.addView(view);
return view;
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {

container.removeView(viewList.get(position));
}
});

viewPager_tab1.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}

@Override
public void onPageSelected(int position) {

setTabImageNormal();
switch (position){
case 0:
ib_know.setImageResource(R.mipmap.btn_know_pre);
tv_know.setTextColor(getResources().getColor(R.color.colorPressed));
break;
case 1:
ib_want_to_know.setImageResource(R.mipmap.btn_wantknow_pre);
tv_want_to_know.setTextColor(getResources().getColor(R.color.colorPressed));
break;
case 2:
ib_my_pager.setImageResource(R.mipmap.btn_my_pre);
tv_my_page.setTextColor(getResources().getColor(R.color.colorPressed));
break;
}
}

@Override
public void onPageScrollStateChanged(int state) {
}
});
}

/**
* 添加View
*/
private void initList() {

LayoutInflater inflater = LayoutInflater.from(this);
View view1 = inflater.inflate(R.layout.view1_tab1,null);
View view2 = inflater.inflate(R.layout.view2_tab1,null);
View view3 = inflater.inflate(R.layout.view3_tab1,null);
viewList.add(view1);
viewList.add(view2);
viewList.add(view3);
}

@Override
public void onClick(View view) {

setTabImageNormal();

switch (view.getId()){
case R.id.ll_tab1_know:
//设置viewpager当前的item
viewPager_tab1.setCurrentItem(0);
ib_know.setImageResource(R.mipmap.btn_know_pre);
tv_know.setTextColor(getResources().getColor(R.color.colorPressed));
break;
case R.id.ll_tab1_want_to_know:
//设置viewpager当前的item
viewPager_tab1.setCurrentItem(1);
ib_want_to_know.setImageResource(R.mipmap.btn_wantknow_pre);
tv_want_to_know.setTextColor(getResources().getColor(R.color.colorPressed));
break;
case R.id.ll_tab1_my_pager:
//设置viewpager当前的item
viewPager_tab1.setCurrentItem(2);
ib_my_pager.setImageResource(R.mipmap.btn_my_pre);
tv_my_page.setTextColor(getResources().getColor(R.color.colorPressed));
break;
default:
break;
}
}

/**
* 使所有Tab图片正常
*/
public void setTabImageNormal(){

ib_know.setImageResource(R.mipmap.btn_know_nor);
ib_want_to_know.setImageResource(R.mipmap.btn_wantknow_nor);
ib_my_pager.setImageResource(R.mipmap.btn_my_nor);
int normalColor = getResources().getColor(R.color.colorNormal);
tv_know.setTextColor(normalColor);
tv_want_to_know.setTextColor(normalColor);
tv_my_page.setTextColor(normalColor);
}
}


效果图一:

仅使用ViewPager

Tab标签切换页面的多种实现方式


Tab实现方案二:

仅使用Fragment(不可滑动,因为没有使用ViewPager之类的组件

APP例子:QQ等

TabActivity2继承的是FragmentActivity


实现原理是:点击Tab标签所在的父布局LinearLayout,调用setOnClickListener方法实现切换页面

主要实现步骤:


布局文件:


activity_tab2.xml

<?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"
android:orientation="vertical">

<include layout="@layout/title_tab1" />

<FrameLayout
android:id="@+id/fl_tab_activity2_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>

<include layout="@layout/bottom_tab1" />

</LinearLayout>

注:TabFragment1、TabFragment2、TabFragment3的布局文件简单地复用了上述的view1_tab1.xml等


Java代码:


TabActivity2.java

package me.hlq.tabdemo;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.view.View;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
/**
* 实现Tab方案二:
* 仅使用Fragment实现
* 但是Fragment不能滑动(如:QQ)(因为没有使用ViewPager之类的组件)
* TabActivity2继承的是FragmentActivity
*
* @author HLQ 2016/10/23
*/
public class TabActivity2 extends FragmentActivity implements View.OnClickListener {

private LinearLayout ll_tab1_know;
private LinearLayout ll_tab1_want_to_know;
private LinearLayout ll_tab1_my_pager;

private ImageButton ib_know;
private ImageButton ib_want_to_know;
private ImageButton ib_my_pager;
private TextView tv_know;
private TextView tv_want_to_know;
private TextView tv_my_page;

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

initView();
setListener();

//默认加载第一个fragment
getSupportFragmentManager().beginTransaction()
.add(R.id.fl_tab_activity2_container,new TabFragment1())
.commit();
}

private void setListener() {

ll_tab1_know.setOnClickListener(this);
ll_tab1_want_to_know.setOnClickListener(this);
ll_tab1_my_pager.setOnClickListener(this);
}

private void initView() {

ll_tab1_know = (LinearLayout) findViewById(R.id.ll_tab1_know);
ll_tab1_want_to_know = (LinearLayout) findViewById(R.id.ll_tab1_want_to_know);
ll_tab1_my_pager = (LinearLayout) findViewById(R.id.ll_tab1_my_pager);
ib_know = (ImageButton) findViewById(R.id.ib_know);
ib_want_to_know = (ImageButton) findViewById(R.id.ib_want_to_know);
ib_my_pager = (ImageButton) findViewById(R.id.ib_my_pager);
tv_know = (TextView) findViewById(R.id.tv_know);
tv_want_to_know = (TextView) findViewById(R.id.tv_want_to_know);
tv_my_page = (TextView) findViewById(R.id.tv_my_page);
}

@Override
public void onClick(View view) {

setTabImageNormal();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

switch (view.getId()) {
case R.id.ll_tab1_know:
ib_know.setImageResource(R.mipmap.btn_know_pre);
tv_know.setTextColor(getResources().getColor(R.color.colorPressed));
transaction.replace(R.id.fl_tab_activity2_container,new TabFragment1());
transaction.commit();

break;
case R.id.ll_tab1_want_to_know:
ib_want_to_know.setImageResource(R.mipmap.btn_wantknow_pre);
tv_want_to_know.setTextColor(getResources().getColor(R.color.colorPressed));
transaction.replace(R.id.fl_tab_activity2_container,new TabFragment2());
transaction.commit();

break;
case R.id.ll_tab1_my_pager:
ib_my_pager.setImageResource(R.mipmap.btn_my_pre);
tv_my_page.setTextColor(getResources().getColor(R.color.colorPressed));
transaction.replace(R.id.fl_tab_activity2_container,new TabFragment3());
transaction.commit();

break;
default:
break;
}
}

/**
* 使所有Tab图片正常
*/
public void setTabImageNormal(){

ib_know.setImageResource(R.mipmap.btn_know_nor);
ib_want_to_know.setImageResource(R.mipmap.btn_wantknow_nor);
ib_my_pager.setImageResource(R.mipmap.btn_my_nor);
int normalColor = getResources().getColor(R.color.colorNormal);
tv_know.setTextColor(normalColor);
tv_want_to_know.setTextColor(normalColor);
tv_my_page.setTextColor(normalColor);
}
}


TabFragment1.java

package me.hlq.tabdemo;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

/**
* A simple {@link Fragment} subclass.
*/
public class TabFragment1 extends Fragment {


public TabFragment1() {
// Required empty public constructor
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.view1_tab1,container,false);
}

}


注:TabFrgament2.java和TabFragment3.java同理


效果图:

仅使用Fragment(不可滑动)

Tab标签切换页面的多种实现方式




Tab实现方案三:

使用ViewPager+Fragment
(外加FragmentPagerAdapter,确保可以滑动切换页面)
(此情景可以看成是方案一的变种,只不过是把页面List中的泛型由View换成Fragment罢了)
因为视图变成了Fragment,所以adapter由PagerAdapter换成FragmentPagerAdapter


实现原理同方案一,List中的泛型由View换成Fragment

主要实现步骤:


布局文件:

复用上文


Java代码:

package me.hlq.tabdemo;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;

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

/**
* Tab实现方案三:
* 使用ViewPager+Fragment
* (外加FragmentPagerAdapter,确保可以滑动切换页面)
*
* (此情景可以看成是方案一的变种,只不过是把页面List中的泛型由View换成Fragment罢了)
* 因为视图变成了Fragment,所以adapter由PagerAdapter换成FragmentPagerAdapter
*
* @author HLQ 2016/10/23
*/
public class TabActivity3 extends FragmentActivity implements View.OnClickListener {

private LinearLayout ll_tab1_know;
private LinearLayout ll_tab1_want_to_know;
private LinearLayout ll_tab1_my_pager;

private ImageButton ib_know;
private ImageButton ib_want_to_know;
private ImageButton ib_my_pager;
private TextView tv_know;
private TextView tv_want_to_know;
private TextView tv_my_page;

private ViewPager viewPager_tab1;

private List<Fragment> fragmentList = new ArrayList<>();

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//这里复用布局一
setContentView(R.layout.activity_tab1);

initView();
setListener();
}

private void setListener() {

ll_tab1_know.setOnClickListener(this);
ll_tab1_want_to_know.setOnClickListener(this);
ll_tab1_my_pager.setOnClickListener(this);
}

private void initView() {

ll_tab1_know = (LinearLayout) findViewById(R.id.ll_tab1_know);
ll_tab1_want_to_know = (LinearLayout) findViewById(R.id.ll_tab1_want_to_know);
ll_tab1_my_pager = (LinearLayout) findViewById(R.id.ll_tab1_my_pager);
ib_know = (ImageButton) findViewById(R.id.ib_know);
ib_want_to_know = (ImageButton) findViewById(R.id.ib_want_to_know);
ib_my_pager = (ImageButton) findViewById(R.id.ib_my_pager);
tv_know = (TextView) findViewById(R.id.tv_know);
tv_want_to_know = (TextView) findViewById(R.id.tv_want_to_know);
tv_my_page = (TextView) findViewById(R.id.tv_my_page);

viewPager_tab1 = (ViewPager) findViewById(R.id.viewPager_tab1);

initList();

viewPager_tab1.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {

@Override
public Fragment getItem(int position) {

return fragmentList.get(position);
}

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

});

viewPager_tab1.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}

@Override
public void onPageSelected(int position) {

setTabImageNormal();
switch (position){
case 0:
//设置viewpager当前的item
viewPager_tab1.setCurrentItem(0);
ib_know.setImageResource(R.mipmap.btn_know_pre);
tv_know.setTextColor(getResources().getColor(R.color.colorPressed));
break;
case 1:
//设置viewpager当前的item
viewPager_tab1.setCurrentItem(1);
ib_want_to_know.setImageResource(R.mipmap.btn_wantknow_pre);
tv_want_to_know.setTextColor(getResources().getColor(R.color.colorPressed));
break;
case 2:
//设置viewpager当前的item
viewPager_tab1.setCurrentItem(2);
ib_my_pager.setImageResource(R.mipmap.btn_my_pre);
tv_my_page.setTextColor(getResources().getColor(R.color.colorPressed));
break;
}
}

@Override
public void onPageScrollStateChanged(int state) {
}
});
}

/**
* 添加View
*/
private void initList() {

TabFragment1 fragment1 = new TabFragment1();
TabFragment2 fragment2 = new TabFragment2();
TabFragment3 fragment3 = new TabFragment3();
fragmentList.add(fragment1);
fragmentList.add(fragment2);
fragmentList.add(fragment3);
}

@Override
public void onClick(View view) {

setTabImageNormal();

switch (view.getId()){
case R.id.ll_tab1_know:
//设置viewpager当前的item
viewPager_tab1.setCurrentItem(0);
ib_know.setImageResource(R.mipmap.btn_know_pre);
tv_know.setTextColor(getResources().getColor(R.color.colorPressed));
break;
case R.id.ll_tab1_want_to_know:
//设置viewpager当前的item
viewPager_tab1.setCurrentItem(1);
ib_want_to_know.setImageResource(R.mipmap.btn_wantknow_pre);
tv_want_to_know.setTextColor(getResources().getColor(R.color.colorPressed));
break;
case R.id.ll_tab1_my_pager:
//设置viewpager当前的item
viewPager_tab1.setCurrentItem(2);
ib_my_pager.setImageResource(R.mipmap.btn_my_pre);
tv_my_page.setTextColor(getResources().getColor(R.color.colorPressed));
break;
default:
break;
}
}

/**
* 使所有Tab图片正常
*/
public void setTabImageNormal(){

ib_know.setImageResource(R.mipmap.btn_know_nor);
ib_want_to_know.setImageResource(R.mipmap.btn_wantknow_nor);
ib_my_pager.setImageResource(R.mipmap.btn_my_nor);
int normalColor = getResources().getColor(R.color.colorNormal);
tv_know.setTextColor(normalColor);
tv_want_to_know.setTextColor(normalColor);
tv_my_page.setTextColor(normalColor);
}
}

效果图:

使用ViewPager+Fragment(可滑动)

Tab标签切换页面的多种实现方式



Tab实现方案四(顶部):

ViewPager+Fragment+TabPageIndicator
(外加FragmentPagerAdapter,确保可以滑动切换页面)
(有指示器的Tab一般位于顶部且不含图标)


TabPageIndicator类是开源类,使用Android Studio需要在build.gradle下添加依赖:

compile 'com.github.JakeWharton:ViewPagerIndicator:2.4.1@aar'


主要实现步骤:


布局文件:

<?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"
android:orientation="vertical">

<include layout="@layout/title_tab1" />

<com.viewpagerindicator.TabPageIndicator
android:id="@+id/title_page_indicator"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"/>

<android.support.v4.view.ViewPager
android:id="@+id/viewPager_tab4"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>


styles.xml

<resources>

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>

<style name="MyTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="vpiTabPageIndicatorStyle">@style/MyWidget.TabPageIndicator</item>
<!--<item name="android:windowBackground">@drawable/init_pic</item>-->
<item name="android:windowNoTitle">true</item>
<item name="android:animationDuration">5000</item>
<item name="android:windowContentOverlay">@null</item>
</style>

<style name="MyWidget.TabPageIndicator" parent="Widget">
<item name="android:gravity">center</item>
<item name="android:background">@drawable/vpi__tab_indicator</item>
<item name="android:paddingLeft">22dip</item>
<item name="android:paddingRight">22dip</item>
<item name="android:paddingTop">8dp</item>
<item name="android:paddingBottom">8dp</item>
<item name="android:textAppearance">@style/MyTextAppearance.TabPageIndicator</item>
<item name="android:textSize">16sp</item>
<item name="android:maxLines">1</item>
</style>


<style name="MyTextAppearance.TabPageIndicator" parent="Widget">
<item name="android:textStyle">bold</item>
<item name="android:textColor">@color/black</item>
</style>
</resources>

清单文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="me.hlq.tabdemo">

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".TabActivity1"/>
<activity android:name=".TabActivity2"/>
<activity android:name=".TabActivity3"/>
<activity android:name=".TabActivity4"
android:theme="@style/MyTheme"/>
<activity android:name=".TabActivity5">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>


Java代码:


TabActivity4.java

package me.hlq.tabdemo;

import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;

import com.viewpagerindicator.TabPageIndicator;

import me.hlq.tabdemo.adapter.Tab4Adapter;

/**
* Tab实现方案四(顶部):
* ViewPager+Fragment+TabPageIndicator
* (外加FragmentPagerAdapter,确保可以滑动切换页面)
*
* (有指示器的Tab一般位于顶部且不含图标)
*
* @author HLQ 2016/10/23
*/
public class TabActivity4 extends AppCompatActivity {

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

ViewPager viewPager_tab4 = (ViewPager) findViewById(R.id.viewPager_tab4);
viewPager_tab4.setAdapter(new Tab4Adapter(getSupportFragmentManager()));

TabPageIndicator title_page_indicator = (TabPageIndicator) findViewById(R.id.title_page_indicator);
//关联TabPageIndicator和ViewPager
title_page_indicator.setViewPager(viewPager_tab4);
}
}

效果图:

ViewPager+Fragment+TabPageIndicator(可滑动)

Tab标签切换页面的多种实现方式



Tab实现方案五:

使用RadioGroup+Fragment实现(不能滑动)


这种实现方法的原理也很简单:通过调用radioGroup的setOnCheckedChangeListener方法实现

点击radioGroup包含的radioButton来切换页面


主要实现步骤:


布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<!-- 标题栏 -->
<include layout="@layout/title_tab1"/>

<!-- FrameLayout -->
<FrameLayout
android:id="@+id/fl_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>

<!-- RadioGroup -->
<RadioGroup
android:id="@+id/radio_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
android:orientation="horizontal">
<!-- android:button="@null"去掉radioButton自带圆圈 -->
<RadioButton
android:id="@+id/rb_know"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:button="@null"
android:padding="10dp"
android:drawablePadding="10dp"
android:gravity="center_horizontal"
android:drawableTop="@drawable/selector_know_btn"
android:textColor="@color/colorNormal"
android:text="知道"/>
<RadioButton
android:id="@+id/rb_want_to_know"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:button="@null"
android:padding="10dp"
android:drawablePadding="10dp"
android:gravity="center_horizontal"
android:drawableTop="@drawable/selector_wantknow_btn"
android:textColor="@color/colorNormal"
android:text="我想知道"/>
<RadioButton
android:id="@+id/rb_my_page"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:button="@null"
android:padding="10dp"
android:drawablePadding="10dp"
android:gravity="center_horizontal"
android:drawableTop="@drawable/selector_my_btn"
android:textColor="@color/colorNormal"
android:text="我的主页"/>
</RadioGroup>

</LinearLayout>

drawable文件夹下的资源文件

selector_know_btn.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

<item android:state_checked="true" android:drawable="@mipmap/btn_know_pre"/>
<item android:drawable="@mipmap/btn_know_nor"/>
</selector>


另外两个资源文件同理


Java代码:

package me.hlq.tabdemo;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.RadioButton;
import android.widget.RadioGroup;

/**
* 实现Tab方案五:
* 使用RadioGroup+Fragment实现
* 但是Fragment不能滑动(如:QQ)(因为没有使用ViewPager之类的组件)
*
* @author HLQ 2016/10/23
*/
public class TabActivity5 extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener{

RadioGroup radioGroup;
RadioButton rb_know;
RadioButton rb_want_to_know;
RadioButton rb_my_page;

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

findViewById();

//默认加载第一个fragment
radioGroup.check(R.id.rb_know);
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fl_container,new TabFragment1(),null)
.commit();
rb_know.setTextColor(getResources().getColor(R.color.colorPressed));
radioGroup.setOnCheckedChangeListener(this);
}

private void findViewById() {

radioGroup = (RadioGroup) findViewById(R.id.radio_group);
rb_know = (RadioButton) findViewById(R.id.rb_know);
rb_want_to_know = (RadioButton) findViewById(R.id.rb_want_to_know);
rb_my_page = (RadioButton) findViewById(R.id.rb_my_page);
}

@Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {

setTabStatusNormal();
switch (i){
case R.id.rb_know:
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fl_container,new TabFragment1(),null)
.commit();
rb_know.setTextColor(getResources().getColor(R.color.colorPressed));
break;
case R.id.rb_want_to_know:
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fl_container,new TabFragment2(),null)
.commit();
rb_want_to_know.setTextColor(getResources().getColor(R.color.colorPressed));
break;
case R.id.rb_my_page:
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fl_container,new TabFragment3(),null)
.commit();
rb_my_page.setTextColor(getResources().getColor(R.color.colorPressed));
break;
}
}

/**
* 使Tab图标正常
*/
private void setTabStatusNormal() {
int normalColor = getResources().getColor(R.color.colorNormal);
rb_know.setTextColor(normalColor);
rb_want_to_know.setTextColor(normalColor);
rb_my_page.setTextColor(normalColor);
}
}<span style="color:#ff0000;">
</span>


效果图:

使用RadioGroup+Fragment实现(不可滑动)

Tab标签切换页面的多种实现方式


以上为Tab标签切换页面的5种实现方式。当然还有其他实现方式,后期补充


源码链接:https://github.com/CalvinHwang123/TabDemo


参考资料:

http://blog.csdn.net/lmj623565791/article/details/24740977

http://blog.csdn.net/wwj_748/article/details/44224945