经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » Android » 查看文章
Android ViewPager2 + Fragment + BottomNavigationView 联动
来源:cnblogs  作者:AskaJohnny  时间:2022/12/2 11:42:15  对本文有异议

Android ViewPager2 + Fragment + BottomNavigationView 联动

本篇主要介绍一下 ViewPager2 + Fragment + BottomNavigationView , 上篇中把ViewPager2和Fragment 联动起来了, 本篇主要把 BottomNavigationView集成进去

2022-11-25 17.31.02

概述

BottomNavigationView 是一个底部导航控件, 现在要实现的效果就是 滑动ViewPager2 中的Fragment 并且底部BottomNavigationView 菜单部分跟着联动 同理反过来 点击BottomNavigationView 的时候 ViewPager2中的Fragment 也对应滑动, 下面来看看如何实现的吧

实现思路

1.Activity 布局文件中引入 ViewPager2 控件
2.编写menu文件 提供给BottomNavigationView 用于展示
3.Activity 布局文件中引入BottomNavigationView 控件
4.编写 Fragment 用于填充到ViewPager2中
5.编写Adapter 实现 FragmentStateAdapter
6.BottomNavigationView添加 setOnItemSelectedListener 联动ViewPager2
7.ViewPager2 添加 registerOnPageChangeCallback 联动 BottomNavigationView

代码实现

下面就来按照上面的思路一步步实现代码啦!

1.Activity 布局文件中引入 ViewPager2 控件

  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. xmlns:tools="http://schemas.android.com/tools"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. tools:context=".ViewPager2BottomActivity">
  8. <androidx.viewpager2.widget.ViewPager2
  9. android:id="@+id/viewpager2bottom"
  10. android:layout_width="match_parent"
  11. android:layout_height="0dp"
  12. app:layout_constraintStart_toStartOf="parent"
  13. app:layout_constraintTop_toTopOf="parent"
  14. app:layout_constraintBottom_toTopOf="@id/bootomnav2"
  15. />
  16. </androidx.constraintlayout.widget.ConstraintLayout>

2.编写menu文件 提供给BottomNavigationView 用于展示

图标icon 自己配置吧

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <menu xmlns:android="http://schemas.android.com/apk/res/android">
  3. <item
  4. android:title="首页"
  5. android:id="@+id/home_item"
  6. android:icon="@drawable/ic_baseline_home_24"
  7. />
  8. <item
  9. android:title="类型"
  10. android:id="@+id/type_item"
  11. android:icon="@drawable/ic_baseline_merge_type_24"
  12. />
  13. <item
  14. android:title="添加"
  15. android:id="@+id/add_item"
  16. android:icon="@drawable/ic_baseline_add_24"
  17. />
  18. <item
  19. android:title="设置"
  20. android:id="@+id/setting_item"
  21. android:icon="@drawable/ic_baseline_settings_24"
  22. />
  23. </menu>

3.Activity 布局文件中引入BottomNavigationView 控件

  1. package com.johnny.slzzing;
  2. import android.os.Bundle;
  3. import androidx.annotation.NonNull;
  4. import androidx.annotation.Nullable;
  5. import androidx.fragment.app.Fragment;
  6. import android.view.LayoutInflater;
  7. import android.view.View;
  8. import android.view.ViewGroup;
  9. import android.widget.TextView;
  10. import org.w3c.dom.Text;
  11. /**
  12. * A simple {@link Fragment} subclass.
  13. * Use the {@link Bottom2Fragment#newInstance} factory method to
  14. * create an instance of this fragment.
  15. */
  16. public class Bottom2Fragment extends Fragment {
  17. // TODO: Rename parameter arguments, choose names that match
  18. // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
  19. private static final String ARG_PARAM1 = "param1";
  20. private static final String ARG_PARAM2 = "param2";
  21. // TODO: Rename and change types of parameters
  22. private String mParam1;
  23. private String mParam2;
  24. public Bottom2Fragment() {
  25. // Required empty public constructor
  26. }
  27. /**
  28. * Use this factory method to create a new instance of
  29. * this fragment using the provided parameters.
  30. *
  31. * @param param1 Parameter 1.
  32. * @param param2 Parameter 2.
  33. * @return A new instance of fragment Bottom2Fragment.
  34. */
  35. // TODO: Rename and change types and number of parameters
  36. public static Bottom2Fragment newInstance(String param1, String param2) {
  37. Bottom2Fragment fragment = new Bottom2Fragment();
  38. Bundle args = new Bundle();
  39. args.putString(ARG_PARAM1, param1);
  40. args.putString(ARG_PARAM2, param2);
  41. fragment.setArguments(args);
  42. return fragment;
  43. }
  44. @Override
  45. public void onCreate(Bundle savedInstanceState) {
  46. super.onCreate(savedInstanceState);
  47. if (getArguments() != null) {
  48. mParam1 = getArguments().getString(ARG_PARAM1);
  49. mParam2 = getArguments().getString(ARG_PARAM2);
  50. }
  51. }
  52. @Override
  53. public View onCreateView(LayoutInflater inflater, ViewGroup container,
  54. Bundle savedInstanceState) {
  55. // Inflate the layout for this fragment
  56. return inflater.inflate(R.layout.fragment_bottom2, container, false);
  57. }
  58. @Override
  59. public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
  60. super.onViewCreated(view, savedInstanceState);
  61. TextView textView = view.findViewById(R.id.textview2);
  62. //把动态传入的参数设置到 textView上
  63. textView.setText(mParam1);
  64. }
  65. }

fragment_bottom2.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. xmlns:tools="http://schemas.android.com/tools"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. tools:context=".ViewPager2BottomActivity">
  8. <androidx.viewpager2.widget.ViewPager2
  9. android:id="@+id/viewpager2bottom"
  10. android:layout_width="match_parent"
  11. android:layout_height="0dp"
  12. app:layout_constraintStart_toStartOf="parent"
  13. app:layout_constraintTop_toTopOf="parent"
  14. app:layout_constraintBottom_toTopOf="@id/bootomnav2"
  15. />
  16. <com.google.android.material.bottomnavigation.BottomNavigationView
  17. android:id="@+id/bootomnav2"
  18. android:layout_width="match_parent"
  19. android:layout_height="wrap_content"
  20. app:layout_constraintTop_toBottomOf="@id/viewpager2bottom"
  21. app:layout_constraintBottom_toBottomOf="parent"
  22. app:layout_constraintStart_toStartOf="parent"
  23. app:menu="@menu/bottom_item_menu"
  24. app:labelVisibilityMode="labeled"
  25. />
  26. <!-- 这个要设置 app:labelVisibilityMode="labeled" 才能显示图标文字 因为我这里超过了3个-->
  27. </androidx.constraintlayout.widget.ConstraintLayout>

4.编写 Fragment 用于填充到ViewPager2中

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:tools="http://schemas.android.com/tools"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. xmlns:app="http://schemas.android.com/apk/res-auto"
  7. tools:context=".Bottom2Fragment">
  8. <!-- TODO: Update blank fragment layout -->
  9. <TextView
  10. android:id="@+id/textview2"
  11. android:layout_width="match_parent"
  12. android:layout_height="match_parent"
  13. android:text="@string/hello_blank_fragment"
  14. app:layout_constraintStart_toStartOf="parent"
  15. app:layout_constraintTop_toTopOf="parent"
  16. android:gravity="center"
  17. android:textSize="25sp"
  18. android:textStyle="bold"
  19. android:textColor="@color/black"
  20. />
  21. </androidx.constraintlayout.widget.ConstraintLayout>

5.编写Adapter 实现 FragmentStateAdapter

上篇已经说过了 直接继承 FragmentStateAdapter

  1. class MyViewPager2BottomAdapter extends FragmentStateAdapter {
  2. List<Fragment> fragmentList;
  3. public MyViewPager2BottomAdapter(@NonNull FragmentActivity fragmentActivity, List<Fragment> list) {
  4. super(fragmentActivity);
  5. this.fragmentList = list;
  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.size();
  15. }
  16. }

6.BottomNavigationView添加 setOnItemSelectedListener 联动ViewPager2

bottomNavigationView.setOnItemSelectedListener核心方法

Acitivity 中实现如下代码:

  1. protected void onCreate(Bundle savedInstanceState) {
  2. super.onCreate(savedInstanceState);
  3. setContentView(R.layout.activity_view_pager2_bottom);
  4. viewPager2 = findViewById(R.id.viewpager2bottom);
  5. bottomNavigationView = findViewById(R.id.bootomnav2);
  6. MyViewPager2BottomAdapter myViewPager2BottomAdapter =
  7. new MyViewPager2BottomAdapter(this,initFragmentList());
  8. viewPager2.setAdapter(myViewPager2BottomAdapter);
  9. //重点 设置 bottomNavigationView 的item 的点击事件 设置viewPager2的联动
  10. bottomNavigationView.setOnItemSelectedListener(new NavigationBarView.OnItemSelectedListener() {
  11. @Override
  12. public boolean onNavigationItemSelected(@NonNull MenuItem item) {
  13. int itemId = item.getItemId();
  14. switch (itemId){
  15. case R.id.home_item:
  16. viewPager2.setCurrentItem(0);
  17. break;
  18. case R.id.type_item:
  19. viewPager2.setCurrentItem(1);
  20. break;
  21. case R.id.add_item:
  22. viewPager2.setCurrentItem(2);
  23. break;
  24. case R.id.setting_item:
  25. viewPager2.setCurrentItem(3);
  26. break;
  27. }
  28. return true;
  29. }
  30. });
  31. }

7.ViewPager2 添加 registerOnPageChangeCallback 联动 BottomNavigationView

  1. protected void onCreate(Bundle savedInstanceState) {
  2. super.onCreate(savedInstanceState);
  3. setContentView(R.layout.activity_view_pager2_bottom);
  4. viewPager2 = findViewById(R.id.viewpager2bottom);
  5. bottomNavigationView = findViewById(R.id.bootomnav2);
  6. MyViewPager2BottomAdapter myViewPager2BottomAdapter =
  7. new MyViewPager2BottomAdapter(this,initFragmentList());
  8. viewPager2.setAdapter(myViewPager2BottomAdapter);
  9. bottomNavigationView.setOnItemSelectedListener(new NavigationBarView.OnItemSelectedListener() {
  10. @Override
  11. public boolean onNavigationItemSelected(@NonNull MenuItem item) {
  12. int itemId = item.getItemId();
  13. switch (itemId){
  14. case R.id.home_item:
  15. viewPager2.setCurrentItem(0);
  16. break;
  17. case R.id.type_item:
  18. viewPager2.setCurrentItem(1);
  19. break;
  20. case R.id.add_item:
  21. viewPager2.setCurrentItem(2);
  22. break;
  23. case R.id.setting_item:
  24. viewPager2.setCurrentItem(3);
  25. break;
  26. }
  27. return true;
  28. }
  29. });
  30. //重点 实现滑动的时候 联动 bottomNavigationView的selectedItem
  31. viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
  32. @Override
  33. public void onPageSelected(int position) {
  34. super.onPageSelected(position);
  35. switch (position){
  36. case 0:
  37. bottomNavigationView.setSelectedItemId(R.id.home_item);
  38. break;
  39. case 1:
  40. bottomNavigationView.setSelectedItemId(R.id.type_item);
  41. break;
  42. case 2:
  43. bottomNavigationView.setSelectedItemId(R.id.add_item);
  44. break;
  45. case 3:
  46. bottomNavigationView.setSelectedItemId(R.id.setting_item);
  47. break;
  48. }
  49. }
  50. });
  51. }

image-20221125172800393

总结

本篇主要介绍了 如何把ViewPager2 + Fragment + BottomNavigationView 集成起来并且实现ViewPager2和BottomNavigationView的双向联动

ViewPager和ViewPager2 一些区别:

  • ViewPager 的 Adapter 继承 FragmentStatePagerAdapter 而 ViewPager2 的Adapter 继承 FragmentStateAdapter
  • ViewPager 滑动监听是 viewPager.addOnPageChangeListener方法 而ViewPager2 滑动监听是 registerOnPageChangeCallback 方法

欢迎大家访问 个人博客 Johnny小屋
欢迎关注个人公众号

欢迎关注个人公众号

原文链接:https://www.cnblogs.com/askajohnny/p/16943985.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号