Android ViewPager2 + Fragment + BottomNavigationView 聯動

来源:https://www.cnblogs.com/askajohnny/archive/2022/12/02/16943985.html
-Advertisement-
Play Games

Android ViewPager2 + Fragment + BottomNavigationView 聯動 本篇主要介紹一下 ViewPager2 + Fragment + BottomNavigationView , 上篇中把ViewPager2和Fragment 聯動起來了, 本篇主要把 B ...


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小屋
歡迎關註個人公眾號

歡迎關註個人公眾號


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在SpringMVC中,控制器負責處理由DIspatchServlet接收並分發過來的請求。它把用戶請求的數據通過業務處理層封裝成一個Model,然後把該model返回給對應的View進行展示。 Controller無需繼承特定的類或實現特定的藉口。只需使用@Controller(@RestCont ...
  • 代碼1 #include <iostream> #include <thread> using namespace std; class A { public: A() { cout << "A()" << endl; } ~A() { cout << "~A()" << endl; } void ...
  • javaweb三大組件 java web:Servlet,Filter,Listener 三大組件的各自功能: Servlet:用我的話來講它就像是一個處理器,它會接受http請求然後把他封裝成 HttpServletRequest 和HttpServletResponse 對象,然後進行處理 Fi ...
  • 1,javaSript var str1="123"; var str2="123"; console.log(str1==str2);//true console.log(str1 str2);//true 這個沒什麼要說的 js裡面引入了嚴格執行的 符號,兩個等號和三個等號的區別在於 1,"== ...
  • Odoo安裝/更新模塊原理 Odoo每次安裝/更新模塊時,會進行以下幾步處理: 1.判斷是否需要創建表,如果需要創建且表不存在,則進行表的創建(不進行欄位的創建); 2.獲取該表中已經存在的欄位; 3.獲取odoo模型中的所有欄位; 4.遍歷欄位,對需要存儲的欄位,進行欄位的更新/創建,欄位屬性的更 ...
  • 前言 為什麼選擇自己開發一個詞典 市面上的詞典都不太彳亍,有Golden Dict和歐陸詞典這類註重詞典文件的,有有道詞典這類電子詞典,前者對於查詞更偏向於內容整合,後者則是釋義與例句。對於翻譯功能,兩者則都沒有整合,個人感覺很是麻煩,所以出於個人需要,決定自行開發。 開發的經歷 因為自己很喜歡UW ...
  • 代碼1 int main(){ //裸指針,手動開闢,需要自己釋放,如果忘記了或者因為 //程式邏輯導致p沒有釋放,那麼就會導致記憶體泄漏 int *p=new int(10); if(***){ retur -1; } delete p; return 0; } 有沒有什麼辦法幫我們管理指針,確保資 ...
  • 我國目前並未出台專門針對網路爬蟲技術的法律規範,但在司法實踐中,相關判決已屢見不鮮,K 哥特設了“K哥爬蟲普法”專欄,本欄目通過對真實案例的分析,旨在提高廣大爬蟲工程師的法律意識,知曉如何合法合規利用爬蟲技術,警鐘長鳴,做一個守法、護法、有原則的技術人員。 案情介紹 谷米公司為開發和運營“酷米客”A ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...