首页 > 其他分享 >Android ViewPager2 + Fragment + BottomNavigationView 联动

Android ViewPager2 + Fragment + BottomNavigationView 联动

时间:2022-12-02 11:44:36浏览次数:52  
标签:Fragment viewPager2 item ViewPager2 Android BottomNavigationView id

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 控件

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ViewPager2BottomActivity">


    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/viewpager2bottom"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@id/bootomnav2"
        />


</androidx.constraintlayout.widget.ConstraintLayout>

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

图标icon 自己配置吧

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

    <item
        android:title="首页"
        android:id="@+id/home_item"
        android:icon="@drawable/ic_baseline_home_24"
        />

    <item
        android:title="类型"
        android:id="@+id/type_item"
        android:icon="@drawable/ic_baseline_merge_type_24"
        />

    <item
        android:title="添加"
        android:id="@+id/add_item"
        android:icon="@drawable/ic_baseline_add_24"
        />

    <item
        android:title="设置"
        android:id="@+id/setting_item"
        android:icon="@drawable/ic_baseline_settings_24"
        />
</menu>

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

package com.johnny.slzzing;

import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import org.w3c.dom.Text;

/**
 * A simple {@link Fragment} subclass.
 * Use the {@link Bottom2Fragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class Bottom2Fragment extends Fragment {

    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;

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

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment Bottom2Fragment.
     */
    // TODO: Rename and change types and number of parameters
    public static Bottom2Fragment newInstance(String param1, String param2) {
        Bottom2Fragment fragment = new Bottom2Fragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_bottom2, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        TextView textView = view.findViewById(R.id.textview2);
        //把动态传入的参数设置到 textView上
        textView.setText(mParam1);
    }
}

fragment_bottom2.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ViewPager2BottomActivity">


    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/viewpager2bottom"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@id/bootomnav2"
        />

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bootomnav2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@id/viewpager2bottom"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:menu="@menu/bottom_item_menu"                                        
        app:labelVisibilityMode="labeled" 
        />
<!-- 这个要设置 app:labelVisibilityMode="labeled"  才能显示图标文字 因为我这里超过了3个-->        
</androidx.constraintlayout.widget.ConstraintLayout>

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

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".Bottom2Fragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:id="@+id/textview2"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/hello_blank_fragment"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:gravity="center"
        android:textSize="25sp"
        android:textStyle="bold"
        android:textColor="@color/black"
        />

</androidx.constraintlayout.widget.ConstraintLayout>

5.编写Adapter 实现 FragmentStateAdapter

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

class MyViewPager2BottomAdapter extends FragmentStateAdapter {

    List<Fragment> fragmentList;
    public MyViewPager2BottomAdapter(@NonNull FragmentActivity fragmentActivity, List<Fragment> list) {
        super(fragmentActivity);
        this.fragmentList = list;
    }

    @NonNull
    @Override
    public Fragment createFragment(int position) {
        return fragmentList.get(position);
    }

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

6.BottomNavigationView添加 setOnItemSelectedListener 联动ViewPager2

bottomNavigationView.setOnItemSelectedListener核心方法

Acitivity 中实现如下代码:

  protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_view_pager2_bottom);

        viewPager2 = findViewById(R.id.viewpager2bottom);
        bottomNavigationView = findViewById(R.id.bootomnav2);
        MyViewPager2BottomAdapter myViewPager2BottomAdapter =
                new MyViewPager2BottomAdapter(this,initFragmentList());
        viewPager2.setAdapter(myViewPager2BottomAdapter);
        //重点 设置 bottomNavigationView 的item 的点击事件 设置viewPager2的联动
        bottomNavigationView.setOnItemSelectedListener(new NavigationBarView.OnItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                int itemId = item.getItemId();
                switch (itemId){
                    case R.id.home_item:
                        viewPager2.setCurrentItem(0);
                        break;
                    case R.id.type_item:
                        viewPager2.setCurrentItem(1);
                        break;
                    case R.id.add_item:
                        viewPager2.setCurrentItem(2);
                        break;
                    case R.id.setting_item:
                        viewPager2.setCurrentItem(3);
                        break;
                }
                return true;
            }
        });

    }

7.ViewPager2 添加 registerOnPageChangeCallback 联动 BottomNavigationView

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_view_pager2_bottom);

    viewPager2 = findViewById(R.id.viewpager2bottom);
    bottomNavigationView = findViewById(R.id.bootomnav2);
    MyViewPager2BottomAdapter myViewPager2BottomAdapter =
            new MyViewPager2BottomAdapter(this,initFragmentList());
    viewPager2.setAdapter(myViewPager2BottomAdapter);

    bottomNavigationView.setOnItemSelectedListener(new NavigationBarView.OnItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            int itemId = item.getItemId();
            switch (itemId){
                case R.id.home_item:
                    viewPager2.setCurrentItem(0);
                    break;
                case R.id.type_item:
                    viewPager2.setCurrentItem(1);
                    break;
                case R.id.add_item:
                    viewPager2.setCurrentItem(2);
                    break;
                case R.id.setting_item:
                    viewPager2.setCurrentItem(3);
                    break;
            }
            return true;
        }
    });
     //重点 实现滑动的时候 联动 bottomNavigationView的selectedItem
    viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
        @Override
        public void onPageSelected(int position) {
            super.onPageSelected(position);
            switch (position){
                case 0:
                    bottomNavigationView.setSelectedItemId(R.id.home_item);
                    break;
                case 1:
                    bottomNavigationView.setSelectedItemId(R.id.type_item);
                    break;
                case 2:
                    bottomNavigationView.setSelectedItemId(R.id.add_item);
                    break;
                case 3:
                    bottomNavigationView.setSelectedItemId(R.id.setting_item);
                    break;
            }
        }
    });

}

image-20221125172800393

总结

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

ViewPager和ViewPager2 一些区别:

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

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

欢迎关注个人公众号

标签:Fragment,viewPager2,item,ViewPager2,Android,BottomNavigationView,id
From: https://www.cnblogs.com/askajohnny/p/16943985.html

相关文章

  • android中的menu和子menu小结
    menu.xml<?xmlversion="1.0"encoding="utf-8"?><menuxmlns:android="http://schemas.android.com/apk/res/android"><itemandroid:id="@+id/Menu1"android:tit......
  • android中的震动
     在android中,可以控制手机进行震动,先是在配置文件中对权限进行配置:<uses-permissionandroid:name="android.permission.VIBRATE"/>public......
  • android tips:从资源文件中读取文件流显示
    在android中,假如有的文本文件,比如TXT放在raw下,要直接读取出来,放到屏幕中显示,可以这样: privatevoiddoRaw(){InputStreamis=this.g......
  • Android实验——ListView的使用
    一、实验要求和目的掌握Android中ListView控件的使用;掌握各种Adapter封装数据的方法;能够熟练应用各种布局管理器和控件进行界面设计。二、实验环境部署有AndroidS......
  • Android Poco初始化时,不大起眼但可能存在坑点的参数们
    1.前言进行Androidpoco初始化的时候,可能大多数同学都是直接在Poco辅助窗里选择Android模式,然后选择自动帮我们补充poco的初始化脚本:这种情况下,我们大多数都不会关注初......
  • Android实验——使用SharedPreferences存储简单数据
    完成如下程序(主Activity界面如图1所示):在图1中点击“参数设置”按钮,启动如图2所示的Activity。在图2中用户输入完用户名后,点击“确定”按钮,将关闭该Activity(此时需要使用S......
  • Unreal Engine 4.27.2在Android平台开发的相关配置
    UnrealEngine4.27.2在Android平台开发的相关配置UE的官方文档上有Android开发的详细介绍,本文记录一下我最近打包Android项目的一些问题和解决办法。另外本文就是为4.27......
  • Android实验——使用Intent回传数据
    一、实验要求和目的掌握使用Intent回传数据的基本方法。掌握GridView控件的使用方法。二、实验环境部署有AndroidStudio和AndroidSDK的主机;建议在机房的HelloWor......
  • Android studio 安装过程中SDK的环境配置问题
    SDK的环境配置问题在之前的某一篇中,我也提到过在Ecplise里面的SDK的环境配置,二者确实不太一样!一、系统环境变量新增一个变量名为:ANDROID_HOME变量值为:浏览到下载SDK的......
  • Android studio软件的安装过程详解
    步骤详解进入官网,下载相关软件官网地址:https://developer.android.google.cn/studio/点击该页面里面的这个按钮,就能够很轻松地完成下载操作:弹出弹窗,继续下一个操作打......