目录
一、TabLayout介绍
二、TabLayout的常用属性和方法
常用属性:
常用方法:
三、适配器介绍
(一)、PagerAdapter介绍:
(二)、FragmentPagerAdapter介绍:
(三)、FragmentStatePagerAdapter介绍:
四、TabLayout+ViewPager例子
MainActivity:
MyFragmentPagerAdapter :
MyFragmentStatePagerAdapter:
MyPagerAdapter :
FirstFragment :
activirt_main:
first_page:
运行结果:
一、TabLayout介绍
TabLayout是Android Support库中的一个控件,它通常与ViewPager结合使用,用于实现多个页面的切换和导航。TabLayout通过标签页的形式展示不同的内容,用户可以通过点击标签页来切换不同的页面。
二、TabLayout的常用属性和方法
常用属性:
-
tabMode
:指定TabLayout的模式。可选值包括:fixed
:固定模式,每个标签页的宽度相等。scrollable
:可滚动模式,适用于较多标签页的情况。 -
tabGravity
:指定标签页在TabLayout中的对齐方式。可选值包括:fill
:填充模式,将标签页平均分配在TabLayout中。center
:居中模式,将标签页居中显示。start
:起始模式,将标签页从起始位置开始排列。 -
tabIndicatorColor
:指定选中标签页底部指示器的颜色。 -
tabIndicatorHeight
:指定选中标签页底部指示器的高度(以像素为单位)。 -
tabBackground
:指定标签页的背景。 -
tabTextAppearance
:指定标签页的文本外观样式。可以使用自定义的样式资源。 -
tabTextColor
:指定标签页的文本颜色。 -
tabSelectedTextColor
:指定选中标签页的文本颜色。 -
tabRippleColor
:指定标签页的点击效果颜色。 -
tabMaxWidth
:指定标签页的最大宽度(以像素为单位)。 -
tabContentStart
:指定标签页内容的起始位置偏移量(以像素为单位)。
常用方法:
1、newTab()
:创建一个新的标签页对象。
TabLayout.Tab tab = tabLayout.newTab();
2、addTab(Tab tab)
:添加一个标签页到TabLayout中。
tabLayout.addTab(tab);
3、removeTab(Tab tab)
:从TabLayout中移除指定的标签页。
tabLayout.removeTab(tab);
4、removeTabAt(int position)
:根据位置移除TabLayout中的标签页。
tabLayout.removeTabAt(position);
5、getTabCount()
:获取TabLayout中标签页的数量。
int count = tabLayout.getTabCount();
6、getTabAt(int position)
:根据位置获取TabLayout中指定的标签页。
TabLayout.Tab tab = tabLayout.getTabAt(position);
7、getSelectedTabPosition()
:获取当前选中的标签页的位置。
int selectedPosition = tabLayout.getSelectedTabPosition();
8、setupWithViewPager(ViewPager viewPager)
:将TabLayout与ViewPager进行关联,实现标签页和页面的同步切换。
tabLayout.setupWithViewPager(viewPager);
9、setTabMode(int mode)
:设置TabLayout的模式,可以是TabLayout.MODE_FIXED
或TabLayout.MODE_SCROLLABLE
。
tabLayout.setTabMode(TabLayout.MODE_FIXED);
10、setTabGravity(int gravity)
:设置标签页在TabLayout中的对齐方式,可以是TabLayout.GRAVITY_FILL
、TabLayout.GRAVITY_CENTER
或TabLayout.GRAVITY_START
。
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
11、setOnTabSelectedListener(OnTabSelectedListener listener)
:设置标签页选中状态监听器,用于监听标签页的选中和取消选中事件。
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
// 处理选中事件
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
// 处理取消选中事件
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
// 处理再次选中事件
}
});
三、适配器介绍
(一)、PagerAdapter介绍:
PagerAdapter是Android中的一个抽象类,用于在ViewPager中管理页面的适配器。它提供了统一的接口和方法,使得我们可以轻松地将不同的页面内容与ViewPager进行绑定并展示。
主要特点和使用方式如下:
-
页面管理:
- PagerAdapter用于管理ViewPager中的页面,每个页面对应一个View。
- 可以根据需要实现自定义的PagerAdapter来管理不同类型的页面。
-
常用方法:
instantiateItem(ViewGroup container, int position)
:根据position创建并返回对应页面的View对象。destroyItem(ViewGroup container, int position, Object object)
:销毁指定位置的页面View对象。getCount()
:返回页面的总数量。isViewFromObject(View view, Object object)
:判断当前的View是否来自于指定的对象。
-
生命周期:
- PagerAdapter会根据需要创建和销毁页面的View对象,并负责管理它们的生命周期。
- 当某个页面不再可见时,对应的View可能会被销毁。当页面重新可见时,会重新创建对应的View对象。
-
数据更新:
- 在PagerAdapter中,可以通过实现相关方法,如
getItemPosition(Object object)
或覆写notifyDataSetChanged()
方法,实现数据的更新和重新加载页面的功能。
- 在PagerAdapter中,可以通过实现相关方法,如
PagerAdapter是一个抽象类,因此不能直接实例化,我们通常会使用其子类,如FragmentPagerAdapter或FragmentStatePagerAdapter,来管理Fragment页面。
总之,PagerAdapter是用于在ViewPager中管理页面的抽象类,通过实现相关方法来创建、销毁和更新页面的View对象。它提供了一种灵活且可扩展的方式,使得我们能够根据需要定制自己的页面适配器。
(二)、FragmentPagerAdapter介绍:
FragmentPagerAdapter
是Android Support Library中的一个类,用于在ViewPager中展示Fragment的适配器。它继承自PagerAdapter
,提供了便捷的方式来管理Fragment的展示和销毁。
使用FragmentPagerAdapter
时,你需要继承该类并实现以下方法:
getItem(int position)
:根据位置获取对应的Fragment对象。getCount()
:获取Fragment的数量。getPageTitle(int position)
:获取指定位置的Fragment的标题(用于TabLayout中展示)。instantiateItem(ViewGroup container, int position)
:创建指定位置的Fragment并添加到容器中。
(三)、FragmentStatePagerAdapter介绍:
FragmentStatePagerAdapter是一个用于在ViewPager中展示Fragment的适配器,它继承自PagerAdapter类,并提供了一种管理Fragment的方式。它适用于有大量Fragment或动态数量的Fragment的场景。
主要特点和使用方式如下:
-
Fragment管理方式:
- FragmentStatePagerAdapter只会保留当前页面及其相邻页面的Fragment实例,而其他页面的Fragment会被销毁。这种方式可以节省内存并提高性能,特别适合于大量的Fragment或者动态数量的Fragment。
- 当页面不再可见时,对应的Fragment可能会被销毁,但它的状态会保存下来,以便在需要时进行恢复。
-
常用方法:
getItem(int position)
:根据position返回对应位置的Fragment实例。getCount()
:返回Fragment的总数量。destroyItem(ViewGroup container,int position,Object object)
:销毁指定位置的Fragment实例。
-
生命周期:
- FragmentStatePagerAdapter会根据需要创建和销毁Fragment实例,以保证内存的高效利用。
- 当某个页面不可见时,对应的Fragment可能会被销毁,但它的状态会被保存。当页面重新可见时,会重新创建对应的Fragment实例。
-
数据加载和更新:
- 在FragmentStatePagerAdapter中,可以使用getItem()方法根据position获取对应位置的Fragment实例,并在该Fragment中加载数据。
- 当数据需要更新时,可以通过通知Fragment进行更新。
总之,FragmentStatePagerAdapter适用于需要处理大量Fragment或动态数量的Fragment的场景。它在内存占用和性能优化方面提供了较好的支持,可以灵活管理Fragment的生命周期,并实现数据的加载和更新。
四、TabLayout+ViewPager例子
MainActivity:
package com.example.viewpagerdemo;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.viewpager.widget.ViewPager;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import com.google.android.material.tabs.TabLayout;
import java.util.ArrayList;
import java.util.List;
/**
* time:2023/7/15
* author: 敬往事一杯酒
*/
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// initFragmentPagerAdapter();
// initFragmentStatePagerAdapter();
initPagerAdapter();
}
/**
* 使用PagerAdapter适配器实现翻转页面
*/
private void initPagerAdapter() {
FragmentManager fragmentManager = getSupportFragmentManager();
ViewPager viewPager = findViewById(R.id.view_pager);
List<View> views = new ArrayList<>();
views.add(getLayoutInflater().inflate(R.layout.first_page,null));
views.add(getLayoutInflater().inflate(R.layout.second_page,null));
views.add(getLayoutInflater().inflate(R.layout.third_page,null));
MyPagerAdapter fragmentAdapter = new MyPagerAdapter(views);
viewPager.setAdapter(fragmentAdapter);
// tabLayout跟viewpager关联
TabLayout tabLayout = findViewById(R.id.tab_layout);
tabLayout.setupWithViewPager(viewPager);
// 设置每个标签的图标
tabLayout.getTabAt(0).setIcon(R.drawable.ic_launcher_background);
tabLayout.getTabAt(1).setIcon(R.drawable.ic_launcher_background);
tabLayout.getTabAt(2).setIcon(R.drawable.ic_launcher_background);
}
/**
* 使用FragmentStatePagerAdapter适配器实现翻转页面
*/
private void initFragmentStatePagerAdapter(){
FragmentManager fragmentManager = getSupportFragmentManager();
ViewPager viewPager = findViewById(R.id.view_pager);
List<Fragment> fragments = new ArrayList<>();
fragments.add(new FirstFragment());
fragments.add(new secondFragment());
fragments.add(new ThirdFragment());
MyFragmentStatePagerAdapter fragmentAdapter = new MyFragmentStatePagerAdapter(fragmentManager,fragments);
viewPager.setAdapter(fragmentAdapter);
// tabLayout跟viewpager关联
TabLayout tabLayout = findViewById(R.id.tab_layout);
tabLayout.setupWithViewPager(viewPager);
// 设置每个标签的图标
tabLayout.getTabAt(0).setIcon(R.drawable.ic_launcher_background);
tabLayout.getTabAt(1).setIcon(R.drawable.ic_launcher_background);
tabLayout.getTabAt(2).setIcon(R.drawable.ic_launcher_background);
}
/**
* 使用FragmentPagerAdapter适配器实现翻转页面
*/
private void initFragmentPagerAdapter(){
FragmentManager fragmentManager = getSupportFragmentManager();
ViewPager viewPager = findViewById(R.id.view_pager);
List<Fragment> fragments = new ArrayList<>();
fragments.add(new FirstFragment());
fragments.add(new secondFragment());
fragments.add(new ThirdFragment());
MyFragmentPagerAdapter fragmentAdapter = new MyFragmentPagerAdapter(fragmentManager,fragments);
viewPager.setAdapter(fragmentAdapter);
// tabLayout跟viewpager关联
TabLayout tabLayout = findViewById(R.id.tab_layout);
tabLayout.setupWithViewPager(viewPager);
// 设置每个标签的图标
tabLayout.getTabAt(0).setIcon(R.drawable.ic_launcher_background);
tabLayout.getTabAt(1).setIcon(R.drawable.ic_launcher_background);
tabLayout.getTabAt(2).setIcon(R.drawable.ic_launcher_background);
}
}
MyFragmentPagerAdapter :
package com.example.viewpagerdemo;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import java.util.List;
/**
* time:2023/7/15
* author: 敬往事一杯酒
*/
public class MyFragmentPagerAdapter extends FragmentPagerAdapter {
private List<Fragment> mFragments;
public MyFragmentPagerAdapter(@NonNull FragmentManager fm, List<Fragment>fragmentList) {
super(fm);
this.mFragments = fragmentList;
}
@NonNull
@Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
@Override
public int getCount() {
return mFragments.size();
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
// 返回每个 Fragment 的标签文本
switch (position) {
case 0:
return "第一页";
case 1:
return "第二页";
case 2:
return "第三页";
default:
return "";
}
}}
MyFragmentStatePagerAdapter:
package com.example.viewpagerdemo;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import java.util.List;
/**
* time:2023/7/15
* author: 敬往事一杯酒
*/
public class MyFragmentStatePagerAdapter extends FragmentStatePagerAdapter {
private List<Fragment> mFragments;
public MyFragmentStatePagerAdapter(@NonNull FragmentManager fm,List<Fragment>fragments) {
super(fm);
mFragments = fragments;
}
@NonNull
@Override
public Fragment getItem(int position) {
switch (position){
case 0:
return new FirstFragment();
case 1:
return new secondFragment();
case 2:
return new ThirdFragment();
default:
return null;
}
}
@Override
public int getCount() {
if (mFragments!=null){
return mFragments.size();
}else {
return 0;
}
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
// 返回每个 Fragment 的标签文本
switch (position) {
case 0:
return "第一页";
case 1:
return "第二页";
case 2:
return "第三页";
default:
return "";
}
}
}
MyPagerAdapter :
package com.example.viewpagerdemo;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.viewpager.widget.PagerAdapter;
import java.util.List;
/**
* time:2023/7/15
* author: 敬往事一杯酒
*/
public class MyPagerAdapter extends PagerAdapter {
private List<View> mList;
public MyPagerAdapter(List<View> list){
this.mList = list;
}
// 返回要滑动的View的个数
@Override
public int getCount() {
return mList.size();
}
// 创建指定位置的页面图
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
container.addView(mList.get(position));
return mList.get(position);
}
// instantiateItem返回的值是否与当前视图一样
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return view==object;
}
// 移除一个给定位置的页面
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
container.removeView(mList.get(position));
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
// 返回每个 Fragment 的标签文本
switch (position) {
case 0:
return "第一页";
case 1:
return "第二页";
case 2:
return "第三页";
default:
return "";
}
}
}
FirstFragment :
package com.example.viewpagerdemo;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
public class FirstFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.first_page,container,false);
}
}
SecondFragment和ThirdFragment代码和布局文件一样。
activirt_main:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="false"
app:tabGravity="fill"
app:tabMode="fixed" />
<androidx.viewpager.widget.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/tab_layout" />
</RelativeLayout>
first_page:
<?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">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="第一个页面"
android:textSize="25sp"
/>
</LinearLayout>