当前位置:   article > 正文

android 关于TabLayout联动ViewPager2 实现底部导航栏_tablayout和viewpager2

tablayout和viewpager2

最近在心血来潮想写在app 不过我关于android可以说是0基础 在写底部导航栏的时候去问了大佬才知道TabLayout和ViewPager 花了两天才看懂...

这里只是简单介绍因为我不准备专门做安卓软件所以在学的途中很多地方没有认真记

介绍

本篇文章使用的代码是Java

这里官方是有将两个进行联动的方法的 当然如果不用也可以做 只不过应该没人会这样写...

TabLayout

关于TabLayout给我的第一感觉是真的强大 而大部分情况TabLayout都是用于做导航栏的(也是暂时没想出来还可以做什么)

ViewPager

而ViewPager主要是用于做页面滚动 滑动页面 等

这里页面滚动和滑动页面是两个东西 页面滚动就是类似于在浏览某宝或新闻网站时遇到的滚动效果 页面滑动是用户用手指滑动页面(左滑或右滑) 而这里的滚动是自动的由程序设置定时器的方式滚动 当然也可以手动滑动 页面滑动只是用户用手指去滑动

代码

layout_main.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. xmlns:tools="http://schemas.android.com/tools"
  5. android:id="@+id/father_layout"
  6. android:layout_width="match_parent"
  7. android:layout_height="match_parent"
  8. android:background="@color/white"
  9. tools:context=".Main">
  10. <androidx.viewpager2.widget.ViewPager2
  11. android:id="@+id/view_pager"
  12. android:layout_width="match_parent"
  13. android:layout_height="match_parent"/>
  14. <com.google.android.material.tabs.TabLayout
  15. android:id="@+id/navigation"
  16. android:layout_width="match_parent"
  17. android:layout_height="wrap_content"
  18. android:layout_alignParentBottom="true"
  19. app:tabGravity="fill"
  20. app:tabIconTint="@color/tab_layout"
  21. app:tabIndicatorFullWidth="true"
  22. app:tabIndicatorGravity="top"
  23. app:tabIndicatorHeight="2dp"
  24. app:tabMode="fixed"
  25. app:tabRippleColor="#ADD8E6"
  26. app:tabUnboundedRipple="true"/>
  27. </RelativeLayout>

可以看到在我的layout_main文件里我定义TabLayout与ViewPager2

需要注意的是这里的ViewPager2和ViewPager是有区别的 一会介绍

由于我没记住TabLayout的属性所以就放文章给大家了....

TabLayout属性介绍:TabLayout属性介绍

Main.java

  1. package com.javabot.demo;
  2. import android.content.Context;
  3. import android.os.Bundle;
  4. import android.view.LayoutInflater;
  5. import android.view.View;
  6. import android.widget.ImageView;
  7. import androidx.annotation.Nullable;
  8. import androidx.appcompat.app.AppCompatActivity;
  9. import androidx.core.content.ContextCompat;
  10. import androidx.fragment.app.Fragment;
  11. import androidx.viewpager2.widget.ViewPager2;
  12. import com.daimajia.androidanimations.library.Techniques;
  13. import com.daimajia.androidanimations.library.YoYo;
  14. import com.google.android.material.tabs.TabLayout;
  15. import com.google.android.material.tabs.TabLayoutMediator;
  16. import com.javabot.demo.fragment.FragmentCommunity;
  17. import com.javabot.demo.fragment.FragmentContact;
  18. import com.javabot.demo.fragment.FragmentDocumentation;
  19. import com.javabot.demo.fragment.FragmentHomePage;
  20. import com.javabot.demo.utils.MyFragmentPagerAdapter;
  21. import com.javabot.demo.utils.svg;
  22. import java.util.ArrayList;
  23. import java.util.List;
  24. /**
  25. * 主程序
  26. *
  27. * @author
  28. */
  29. public class Main extends AppCompatActivity {
  30. private final Context context = this;
  31. /**
  32. * 工具 svg对象
  33. */
  34. private final svg svg = new svg(context);
  35. private int[] tabIconView = {
  36. R.drawable.home,
  37. R.drawable.megaphone,
  38. R.drawable.paper_plane,
  39. R.drawable.user
  40. };
  41. /**
  42. * 自定义view
  43. *
  44. * @param icon svg
  45. * @return View
  46. */
  47. private View setCustomView(int icon) {
  48. View v = View.inflate(context, R.layout.custom_view, null);
  49. ImageView i = v.findViewById(R.id.CustomViewImage);
  50. i.setImageTintList(ContextCompat.getColorStateList(context, R.color.tab_layout));
  51. i.setImageDrawable(svg.svgImage(icon));
  52. return v;
  53. }
  54. /**
  55. * TabLayout关联ViewPager2
  56. */
  57. private void addMyFragmentPagerAdapter() {
  58. List<Fragment> fragmentList = new ArrayList<>();
  59. FragmentHomePage homePage = new FragmentHomePage();
  60. FragmentCommunity community = new FragmentCommunity();
  61. FragmentContact contact = new FragmentContact();
  62. FragmentDocumentation documentation = new FragmentDocumentation(context);
  63. fragmentList.add(homePage);
  64. fragmentList.add(community);
  65. fragmentList.add(contact);
  66. fragmentList.add(documentation);
  67. MyFragmentPagerAdapter fragmentAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager(),getLifecycle(), fragmentList);
  68. TabLayout tabLayout = findViewById(R.id.navigation);
  69. ViewPager2 viewPager = findViewById(R.id.view_pager);
  70. viewPager.setAdapter(fragmentAdapter);
  71. new TabLayoutMediator(tabLayout, viewPager,
  72. (tab, position) -> {
  73. tab.setIcon(tabIconView[position]);
  74. }
  75. ).attach();
  76. // 监听页面切换事件
  77. viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
  78. @Override
  79. public void onPageSelected(int position) {
  80. // 更新TabLayout的选中状态
  81. tabLayout.selectTab(tabLayout.getTabAt(position));
  82. tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
  83. @Override
  84. public void onTabSelected(TabLayout.Tab tab) {
  85. }
  86. @Override
  87. public void onTabUnselected(TabLayout.Tab tab) {
  88. }
  89. @Override
  90. public void onTabReselected(TabLayout.Tab tab) {
  91. YoYo.with(Techniques.RubberBand)
  92. .duration(700)
  93. .playOn(tab.view);
  94. }
  95. });
  96. }
  97. });
  98. }
  99. @Override
  100. protected void onCreate(@Nullable Bundle savedInstanceState) {
  101. super.onCreate(savedInstanceState);
  102. setContentView(R.layout.layout_main);
  103. addMyFragmentPagerAdapter();
  104. }
  105. }

主要关联的代码在addMyFragmentPagerAdapter方法中

这里我们将代码一点点拆解介绍

addMyFragmentPagerAdapte方法

这里的代码都是按照addMyFragmentPagerAdapte方法中的代码一行一行的讲解 所以看到不知道的变量时请往上瞅瞅

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

这里是创建视图存储器的 这个就看各位喜好了 也可以用Map或数组

ViewPager2的视图对象需要是Fragment而不是View 因为适配器需要

关于ViewPager2的详细介绍请移步

ViewPagers2

  1. FragmentHomePage homePage = new FragmentHomePage();
  2. FragmentCommunity community = new FragmentCommunity();
  3. FragmentContact contact = new FragmentContact();
  4. FragmentDocumentation documentation = new FragmentDocumentation(context);
  5. fragmentList.add(homePage);
  6. fragmentList.add(community);
  7. fragmentList.add(contact);
  8. fragmentList.add(documentation);

创建视图对象并添加到集合中 这一步没什么好说的 视图对象会在下面放出来

MyFragmentPagerAdapter fragmentAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager(),getLifecycle(), fragmentList);

创建适配器对象 适配器会在下面放出来

  1. TabLayout tabLayout = findViewById(R.id.navigation);
  2. ViewPager2 viewPager = findViewById(R.id.view_pager);

获取xml文件中的视图id 这里也没什么好说的

viewPager.setAdapter(fragmentAdapter);

设置ViewPager2适配器fragmentAdapter由适配器对象获得

  1. new TabLayoutMediator(tabLayout, viewPager,
  2. (tab, position) -> {
  3. tab.setIcon(tabIconView[position]);
  4. }).attach();

将TabLayout和ViewPager2关联

而这里的

tab.setIcon(tabIconView[position]);

就是在里面的代码是用于设置TabLayout显示的内容的 这边这个可以自己按需求更改

  1. // 监听页面切换事件
  2. viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
  3. @Override
  4. public void onPageSelected(int position) {
  5. // 更新TabLayout的选中状态
  6. tabLayout.selectTab(tabLayout.getTabAt(position));
  7. tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
  8. @Override
  9. public void onTabSelected(TabLayout.Tab tab) {
  10. }
  11. @Override
  12. public void onTabUnselected(TabLayout.Tab tab) {
  13. }
  14. @Override
  15. public void onTabReselected(TabLayout.Tab tab) {
  16. YoYo.with(Techniques.RubberBand)
  17. .duration(700)
  18. .playOn(tab.view);
  19. }
  20. });
  21. }
  22. });

这里就和备注的一样 和平常的监听事件相同这里可写可不写

需要拿出来说的是

  1. YoYo.with(Techniques.RubberBand)
  2. .duration(700)
  3. .playOn(tab.view);

这是一个名叫悠悠球的动画库

这里是官网介绍:YoYo

依赖如下

  1. //悠悠球动画库
  2. implementation 'com.daimajia.androidanimations:library:2.4@aar'

适配器 FragmentStateAdapter对象

  1. package com.javabot.demo.utils;
  2. import static androidx.viewpager.widget.PagerAdapter.POSITION_NONE;
  3. import androidx.annotation.NonNull;
  4. import androidx.fragment.app.Fragment;
  5. import androidx.fragment.app.FragmentActivity;
  6. import androidx.fragment.app.FragmentManager;
  7. import androidx.lifecycle.Lifecycle;
  8. import androidx.viewpager2.adapter.FragmentStateAdapter;
  9. import java.util.List;
  10. /**
  11. * 适配器对象
  12. * @author
  13. */
  14. public class MyFragmentPagerAdapter extends FragmentStateAdapter {
  15. private final List<Fragment> fragmentList;
  16. public MyFragmentPagerAdapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle, List<Fragment> fragmentList) {
  17. super(fragmentManager, lifecycle);
  18. this.fragmentList = fragmentList;
  19. }
  20. public MyFragmentPagerAdapter(FragmentActivity fm, List<Fragment> fragmentList) {
  21. super(fm);
  22. this.fragmentList=fragmentList;
  23. }
  24. @NonNull
  25. @Override
  26. public Fragment createFragment(int position) {
  27. return fragmentList.get(position);
  28. }
  29. @Override
  30. public int getItemCount() {
  31. return fragmentList.size();
  32. }
  33. @Override
  34. public long getItemId(int position) {
  35. return fragmentList.get(position).hashCode();
  36. }
  37. }

这里的适配器你需要重写的方法有getItemCount和createFragment

这里也只介绍这两个方法

getItemCount方法

此方法返回的是视图的个数 例如我想要显示4个视图那就返回4 如果我给适配器传的视图有6个或者更多但是这个方法只返回4那也只会显示4个视图

createFragment方法

这个方法返回的是视图而此方法中的参数position 代表当前是哪个视图 返回对应视图的下标(从0开始)

例如我在这个方法中写if判断 position==0 再返回某个视图对象 那他的意思其实就是当用户点击到下标为0的那个选项时(或滑动)当前视图显示的内容就是我这里所返回的视图内容

视图文件 Fragment对象

  1. package com.javabot.demo.fragment;
  2. import android.os.Bundle;
  3. import android.view.LayoutInflater;
  4. import android.view.View;
  5. import android.view.ViewGroup;
  6. import androidx.annotation.NonNull;
  7. import androidx.annotation.Nullable;
  8. import androidx.fragment.app.Fragment;
  9. import com.javabot.demo.R;
  10. /**
  11. * 主页视图
  12. */
  13. public class FragmentHomePage extends Fragment {
  14. @Nullable
  15. @Override
  16. public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
  17. return inflater.inflate(R.layout.home_page,container,false);
  18. }
  19. }

剩下的和这个一样就不发出来了

和视图文件所对应的xml文件

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent">
  5. <TextView
  6. android:layout_width="wrap_content"
  7. android:layout_height="wrap_content"
  8. android:text="主页"/>
  9. </RelativeLayout>

这里都差不多就不放出来了

效果图

d7f519f265a349d698e0aff288744822.gif

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/450044
推荐阅读
相关标签
  

闽ICP备14008679号