【Android】ViewPager2和TabLayout协同使用,实现多Fragment页面切换类似于 ...

打印 上一主题 下一主题

主题 510|帖子 510|积分 1530

一、ViewPager2的基本用法

使用前先添加依靠:
  1.    implementation 'androidx.appcompat:appcompat:1.4.0' // AndroidX AppCompat
  2.     implementation 'com.google.android.material:material:1.4.0' // Material Design Components
复制代码
1、制作Fragment

首先制作一个Fragment的xml结构页面
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.     xmlns:app="http://schemas.android.com/apk/res-auto"
  4.     android:layout_width="match_parent"
  5.     android:layout_height="match_parent">
  6.     <TextView
  7.         android:layout_width="wrap_content"
  8.         android:layout_height="wrap_content"
  9.         android:gravity="center"
  10.         android:text="SSSSS"
  11.         android:textSize="19sp"
  12.         app:layout_constraintBottom_toBottomOf="parent"
  13.         app:layout_constraintEnd_toEndOf="parent"
  14.         app:layout_constraintStart_toStartOf="parent"
  15.         app:layout_constraintTop_toTopOf="parent" />
  16. </androidx.constraintlayout.widget.ConstraintLayout>
复制代码
然后使用Fragment类绑定这个结构
  1. public class HomeFragment extends Fragment {
  2.     FragmentBinding binding;
  3.     @Nullable
  4.     @Override
  5.     public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
  6.         binding = FragmentBinding.inflate(inflater,container,false);
  7.         return binding.getRoot();
  8.     }
  9.     @Override
  10.     public void onDestroyView() {
  11.         super.onDestroyView();
  12.         binding = null;
  13.     }
  14. }
复制代码
2、制作Adapter

  1.         <androidx.viewpager2.widget.ViewPager2
  2.             android:id="@+id/viewPager"
  3.             android:layout_width="match_parent"
  4.             android:layout_height="match_parent" />
复制代码
自界说本身的Adapter继续FragmentStateAdapter
制作一个fragmentList管理全部的fragment
  1. public class MyPagerAdapter extends FragmentStateAdapter {
  2.     List<Fragment> fragmentList;    //管理所有的fragment
  3.     public MyPagerAdapter(@NonNull FragmentActivity fragmentActivity, List<Fragment> fragmentList) {
  4.         super(fragmentActivity);
  5.         this.fragmentList = fragmentList;
  6.     }
  7.     @NonNull
  8.     @Override
  9.     public Fragment createFragment(int position) {
  10.         return fragmentList.get(position);
  11.     }
  12.     @Override
  13.     public int getItemCount() {
  14.         return fragmentList != null ? fragmentList.size() : 0;
  15.     }
  16. }
复制代码
createFragment:用于返回指定的frgment界面
getItemCount:用于加载容器巨细
除此之外,FragmentStateAdapter有三个构造方法剩下两个分别是:
  1. public FragmentStateAdapter(@NonNull Fragment fragment)
  2. public FragmentStateAdapter(@NonNull FragmentManager fragmentManager,@NonNull Lifecycle lifecycle)
复制代码
FragmentStateAdapter(Fragment fragment)
这个构造方法通常用于在 Fragment 内部创建 FragmentStateAdapter,并将其附加到该 Fragment 的生命周期。
  1. public class MyFragment extends Fragment {
  2.     private ViewPager2 viewPager;
  3.     private FragmentStateAdapter adapter;
  4.     @Override
  5.     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
  6.         View rootView = inflater.inflate(R.layout.fragment_layout, container, false);
  7.         // 初始化 ViewPager2
  8.         viewPager = rootView.findViewById(R.id.viewPager);
  9.         // 创建适配器并将其附加到当前 Fragment 的生命周期
  10.         adapter = new MyFragmentStateAdapter(this);
  11.         viewPager.setAdapter(adapter);
  12.         return rootView;
  13.     }
  14. }
复制代码
FragmentStateAdapter(FragmentManager fragmentManager, Lifecycle lifecycle)
这个构造方法通常用于在活动中创建 FragmentStateAdapter,并通过提供 FragmentManager 和 Lifecycle 对象来管理 Fragment 的生命周期。
  1. public class MainActivity extends AppCompatActivity {
  2.     private ViewPager2 viewPager;
  3.     private FragmentStateAdapter adapter;
  4.     @Override
  5.     protected void onCreate(Bundle savedInstanceState) {
  6.         super.onCreate(savedInstanceState);
  7.         setContentView(R.layout.activity_main);
  8.         // 初始化 ViewPager2
  9.         viewPager = findViewById(R.id.viewPager);
  10.         // 创建适配器并将其附加到活动的生命周期
  11.         adapter = new MyFragmentStateAdapter(getSupportFragmentManager(), getLifecycle());
  12.         viewPager.setAdapter(adapter);
  13.     }
  14. }
复制代码
3、使用Adapter加载fragment页面

  1.         List<Fragment> fragmentList = new ArrayList<>();
  2.         fragmentList.add(new HomeFragment());
  3.         fragmentList.add(new HomeFragment());
  4.         fragmentList.add(new HomeFragment());
  5.         fragmentList.add(new HomeFragment());
  6.         fragmentList.add(new HomeFragment());
  7.         fragmentList.add(new HomeFragment());
  8.         fragmentList.add(new HomeFragment());
  9.         fragmentList.add(new HomeFragment());
  10.         MyPagerAdapter adapter = new MyPagerAdapter(this,fragmentList);
  11.         //禁用预加载
  12.         binding.viewPager.setOffscreenPageLimit(ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT);
  13.         binding.viewPager.setAdapter(adapter);
复制代码
预加载是在页面还未滑动时,提前加载页面。一样平常默认加载1个页面。
FragmentStateAdapter内部封装有 FragmentManager和 FragmentTransaction,用于管理Fragment;
使用FragmentManager可以根据ID或TAG来查找Fragment , 动态添加、删除、替换
让Fragment 成为ViewPager的一页时,FragmentManager会不绝保存管理创建好了的Fragment,即使当前不是显示的这一页,Fragment对象也不会被烧毁,在配景冷静等待重新显示。但如果Fragment不再可见时,它的视图层次会被烧毁掉,下次显示时视图会重新创建
二、ViewPager2和TabLayout协同使用

1、制作TabLayout与ViewPager2结构文件

  1.     <LinearLayout
  2.         android:layout_width="match_parent"
  3.         android:layout_height="match_parent"
  4.         android:orientation="vertical">
  5.         <com.google.android.material.tabs.TabLayout
  6.             android:id="@+id/tabMode"
  7.             android:layout_width="wrap_content"
  8.             android:layout_height="wrap_content"
  9.             app:tabIndicatorColor="#1E90FF"
  10.             app:tabIndicatorAnimationMode="elastic"
  11.             app:tabSelectedTextColor="#B22222"
  12.             app:tabUnboundedRipple="true"
  13.             app:tabGravity="center"
  14.             app:tabMode="auto" >
  15.         </com.google.android.material.tabs.TabLayout>
  16.         <androidx.viewpager2.widget.ViewPager2
  17.             android:id="@+id/viewPager"
  18.             android:layout_width="match_parent"
  19.             android:layout_height="match_parent"
  20.             android:orientation="horizontal"/>
  21.         
  22.     <!-- ViewPager2内部通过RecyclerView 所以需要通过orientation来设置页面切换方向-->
  23.         
  24.     </LinearLayout>
复制代码
**tabIndicatorAnimationMode ** :设置加载动画样式,elastic表现粘粘性动画,linear表现线性动画
tabIndicatorColor :指示器颜色
tabIndicatorHeight :指示器高度
tabIndicatorFullWidth :设置为false 则指示器跟文本宽度一致
tabUnboundedRipple :设置为true点击时会有一个水波纹结果
tabGravity :可设置center或fill;center指的是居中显示,fill指的是沾满全屏。
tabMode :可设置fixed和 scrollable;fixed:指的是固定tab;scrollable指的是tab可滑动。
tabTextColor :tab笔墨颜色
tabSelectedTextColor :选中时的tab颜色

关于更多的TabLayou的使用可以参考:Android控件-TabLayout使用介绍
2、绑定TabLayout到ViewPager2

2.1 动态自界说Tab

这里采取了自界说TabView的方式,同样的也可以直接使用tab修改样式。
  1.         new TabLayoutMediator(binding.tabMode, binding.viewPager, new TabLayoutMediator.TabConfigurationStrategy() {
  2.             @Override
  3.             public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
  4.                 //自定义TabView
  5.                 TextView tabView = new TextView(MainActivity.this);
  6.                 tabView.setText("Fragment " + position);
  7.                 //将tabbView绑定到tab
  8.                 tab.setCustomView(tabView);
  9.             }
  10.         }).attach();
复制代码
注意一定要使用.attach()进行启动。
2.2 静态自界说Tab——tabTextAppearance

设置笔墨的巨细和样式,在values下新建文件如下:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <resources>
  3.     <style name="tabDome">
  4.         <item name="android:textSize">20sp</item>
  5.         <item name="android:textStyle">bold</item>
  6.     </style>
  7. </resources>
复制代码
在TabLayout中导入文件即可

3、Viewpager2的滑动监听变乱

ViewPager2.OnPageChangeCallback有三个构造方法:
  1.         binding.viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
  2.             //该方法开始滑动到滑动结束前不断调用
  3.             // 参数一:position表示当前页面的位置(当前页面在翻页适配器中的下标,索引),因为不断调用,position也可能表示目标页面的下标
  4.             // 参数二:positionOffset表示页面偏移的百分比,翻页时不断增大(不断趋近1),最后翻页完成时突变成0
  5.             // 这个参数在左滑时由1趋近0,右滑由0趋近1
  6.             // 参数三:positionOffsetPixel表示页面完成滑动的像素数,变化趋势和positionOffset一样
  7.             @Override
  8.             public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
  9.                 super.onPageScrolled(position, positionOffset, positionOffsetPixels);
  10.             }
  11.             //该方法在页面切换成功后调用(滑动前与滑动后不是同一页面)
  12.             //position表示当前页面在适配器中的下标,索引
  13.             @Override
  14.             public void onPageSelected(int position) {
  15.                 super.onPageSelected(position);
  16.             }
  17.             //该方法在页面滑动状态改变时调用
  18.             // ViewPager2.SCROLL_STATE_IDLE表示空闲状态,当前页面处于静止状态,没有要翻页的趋势 == 0
  19.             // ViewPager2.SCROLL_STATE_DRAGGING表示拖动状态,用户正在拖动页面,准备进行翻页滚动 == 1
  20.             // ViewPager2.SCROLL_STATE_SETTLING表示滚动状态,页面正在自动滚动到目标页面 == 2
  21.             @Override
  22.             public void onPageScrollStateChanged(int state) {
  23.                 super.onPageScrollStateChanged(state);
  24.             }
  25.         });
复制代码
3.1 使用动态方法实现字体巨细颜色变革

监听ViewPager2的页面滑动实现修改tab
  1.         //viewPager 页面切换监听
  2.         binding.viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
  3.             
  4.             //用于回调ViewPager2的当前页面,当页面发送变化就会调用这个方法onPageSelected
  5.             @Override
  6.             public void onPageSelected(int position) {
  7.                 //获取总的TabLayout的个数
  8.                 int tabCount = binding.tabMode.getTabCount();
  9.                 //遍历选择所有的Tab,如果判断是当前的Tab则进行相关操作,不是则还原操作
  10.                 for (int i = 0; i < tabCount; i++) {
  11.                     TabLayout.Tab tab = binding.tabMode.getTabAt(i);    //取得tab
  12.                     
  13.                     //通过tab获取tabView
  14.                     TextView tabView = (TextView) tab.getCustomView();
  15.                     if (tab.getPosition() == position) {
  16.                         tabView.setTextSize(20);
  17.                         tabView.setTypeface(Typeface.DEFAULT_BOLD);
  18.                         tabView.setTextColor(Color.parseColor("#B22222"));
  19.                     } else {
  20.                         tabView.setTextSize(15);
  21.                         tabView.setTypeface(Typeface.MONOSPACE);
  22.                         tabView.setTextColor(Color.parseColor("#000000"));
  23.                     }
  24.                 }
  25.             }
  26.         });
复制代码
3.2 使用静态的方法实现字体巨细和颜色变革

首先设置静态的style选项卡,在values下新建一个xml文件
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <resources>
  3.     <style name="TabLayoutTextSelected">
  4.         <item name="android:textSize">20sp</item>
  5.         <item name="android:textColor">#B22222</item>
  6.     </style>
  7.     <style name="TabLayoutTextUnSelected">
  8.         <item name="android:textSize">15sp</item>
  9.         <item name="android:textColor">#000080</item>
  10.     </style>
  11. </resources>
复制代码
然后在TabLayout的结构文件中设置初始状态的tab颜色字体
  1.     <LinearLayout
  2.         android:layout_width="match_parent"
  3.         android:layout_height="match_parent"
  4.         android:orientation="vertical">
  5.         <com.google.android.material.tabs.TabLayout
  6.             android:id="@+id/tabMode"
  7.             android:layout_width="wrap_content"
  8.             android:layout_height="wrap_content"
  9.             app:tabIndicatorColor="#1E90FF"
  10.             app:tabUnboundedRipple="true"
  11.             app:tabGravity="center"
  12.             app:tabMode="auto"
  13.             app:tabTextAppearance="@style/TabLayoutTextUnSelected">        //注意在这个地方使用tabTextAppearance设置初始状态tab的文字效果
  14.         </com.google.android.material.tabs.TabLayout>
  15.         <androidx.viewpager2.widget.ViewPager2
  16.             android:id="@+id/viewPager"
  17.             android:layout_width="match_parent"
  18.             android:layout_height="match_parent"
  19.             android:orientation="horizontal"/>
  20.     </LinearLayout>
复制代码
监听TabLayout实现修改,TabLayout监听变乱有三个Override方法,当然这里也可以继续使用ViewPager2页面的监听方法实现。
  1.         binding.tabMode.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
  2.             //选中时的变化
  3.             @Override
  4.             public void onTabSelected(TabLayout.Tab tab) {
  5.                 // 创建新的 TextView 实例,并设置样式和文本
  6.                 TextView selectedTextView = new TextView(MainActivity.this);
  7.                 selectedTextView.setTextAppearance(R.style.TabLayoutTextSelected);        //在这里动态使用刚刚的style文件
  8.                 selectedTextView.setText("Fragment " + tab.getPosition());        //设置文字内容,tab因为是重新加载的textView内容,所以原来的数据被覆盖掉了
  9.                 tab.setCustomView(selectedTextView);
  10.             }
  11.             //未选中时的变化
  12.             @Override
  13.             public void onTabUnselected(TabLayout.Tab tab) {
  14.                 // 清除未选中标签的自定义视图
  15.                 tab.setCustomView(null);
  16.             }
  17.             //重复选中的变化,当用户再次点击已经选中的Tab时,这个方法就会被调用。
  18.             @Override
  19.             public void onTabReselected(TabLayout.Tab tab) {
  20.                 // 处理标签重新选择,如果需要
  21.             }
  22.         });
复制代码
注意点:
1、在onTabSelected中重新设置加载的文本内容,否则原数据会被覆盖,出现这样的情况

2、在onTabUnselected中一定要扫除覆盖在tab的自界说视图否则视图会不绝重复的加在tab上面,出现这样的情况:

4、TabLayout的监听变乱

  1.         binding.tabMode.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
  2.             TextView textView = new TextView(MainActivity.this);
  3.             @Override
  4.             public void onTabSelected(TabLayout.Tab tab) {
  5.                 //选中时的变化
  6.             }
  7.             public void onTabUnselected(TabLayout.Tab tab) {
  8.                 //未选中的变化
  9.             }
  10.             @Override
  11.             public void onTabReselected(TabLayout.Tab tab) {
  12.                 //重复选中的变化,当用户再次点击已经选中的Tab时,这个方法就会被调用。
  13.             }
  14.         });
复制代码
5、禁止Viewpager2左右滑动翻页

  1.         //false表示禁止,true表示允许
  2.         binding.viewPager.setUserInputEnabled(false);
复制代码
此时就只能通过点击Tab才气加载Fragment.
6、TabLayout+Viewpager2结果展示



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

祗疼妳一个

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表