Android ViewPager2 + Fragment + BottomNavigationView 聯動 本篇主要介紹一下 ViewPager2 + Fragment + BottomNavigationView , 上篇中把ViewPager2和Fragment 聯動起來了, 本篇主要把 B ...
Android ViewPager2 + Fragment + BottomNavigationView 聯動
本篇主要介紹一下 ViewPager2 + Fragment + BottomNavigationView , 上篇中把ViewPager2和Fragment 聯動起來了, 本篇主要把 BottomNavigationView集成進去
概述
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;
}
}
});
}
總結
本篇主要介紹了 如何把ViewPager2 + Fragment + BottomNavigationView 集成起來並且實現ViewPager2和BottomNavigationView的雙向聯動
ViewPager和ViewPager2 一些區別
:
- ViewPager 的 Adapter 繼承 FragmentStatePagerAdapter 而 ViewPager2 的Adapter 繼承 FragmentStateAdapter
- ViewPager 滑動監聽是 viewPager.addOnPageChangeListener方法 而ViewPager2 滑動監聽是 registerOnPageChangeCallback 方法
歡迎大家訪問 個人博客 Johnny小屋
歡迎關註個人公眾號