目录
第七章:多页面组件结合实践:ViewPager2 与 Fragment 的联动
☑ 示例:创建三个 Fragment(PageOneFragment、PageTwoFragment、PageThreeFragment)
🔄 7.4 ViewPager2 配合 FragmentAdapter
8. fragment_news.xml / fragment_image.xml / fragment_list.xml
第七章:多页面组件结合实践:ViewPager2 与 Fragment 的联动
📖 7.1 ViewPager2 简介
ViewPager2
是 ViewPager
的升级版,用于滑动切换页面,常用于多页面布局,如首页、功能页、我的界面等。
特点:
-
支持垂直和水平滑动
-
原生支持
Fragment
-
支持 RecyclerView 优化性能
📦 7.2 准备工作
☑ 添加依赖(通常已默认)
dependencies {
implementation 'androidx.viewpager2:viewpager2:1.0.0'
}
☑ 布局文件 activity_main.xml
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
📚 7.3 创建多个 Fragment 页面
☑ 示例:创建三个 Fragment(PageOneFragment、PageTwoFragment、PageThreeFragment)
public class PageOneFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
TextView tv = new TextView(getContext());
tv.setText("页面一");
tv.setGravity(Gravity.CENTER);
return tv;
}
}
(其他两个 Fragment 类似,仅文字不同)
🔄 7.4 ViewPager2 配合 FragmentAdapter
☑ 在 MainActivity.java
中绑定适配器:
public class MainActivity extends AppCompatActivity {
private ViewPager2 viewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = findViewById(R.id.viewPager);
List<Fragment> fragments = new ArrayList<>();
fragments.add(new PageOneFragment());
fragments.add(new PageTwoFragment());
fragments.add(new PageThreeFragment());
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentStateAdapter adapter = new FragmentStateAdapter(fragmentManager, getLifecycle()) {
@NonNull
@Override
public Fragment createFragment(int position) {
return fragments.get(position);
}
@Override
public int getItemCount() {
return fragments.size();
}
};
viewPager.setAdapter(adapter);
}
}
🎯 7.5 TabLayout 联动(附加功能)
如果你希望顶部加上页签导航:
☑ 添加 TabLayout 依赖
implementation 'com.google.android.material:material:1.4.0'
☑ 修改布局文件
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
☑ 联动代码(在 MainActivity 中):
TabLayout tabLayout = findViewById(R.id.tabLayout);
new TabLayoutMediator(tabLayout, viewPager,
(tab, position) -> {
switch (position) {
case 0: tab.setText("首页"); break;
case 1: tab.setText("发现"); break;
case 2: tab.setText("我的"); break;
}
}
).attach();
📌 本章小结
功能 | 实现方式 |
---|---|
页面切换 | ViewPager2 配合 Fragment |
页面适配 | FragmentStateAdapter |
联动页签 | TabLayout + TabLayoutMediator |
多页面复用 | Fragment + RecyclerView 优化 |
🧪 实战练习
-
添加底部导航(BottomNavigationView)与 ViewPager2 联动
-
让每个 Fragment 显示不同内容:如新闻、图片、列表
-
在 Fragment 中使用 RecyclerView 展示数据
📢 下一章预告:
第八章:本地存储机制详解(SharedPreferences 与 SQLite 数据库)
习题答案
项目结构
MainActivity.java
NewsFragment.java
ImageFragment.java
ListFragment.java
MyAdapter.java
activity_main.xml
fragment_news.xml
fragment_image.xml
fragment_list.xml
item_layout.xml
1. MainActivity.java
package com.example.demo;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.viewpager2.widget.ViewPager2;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private ViewPager2 viewPager;
private BottomNavigationView bottomNavigationView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = findViewById(R.id.viewPager);
bottomNavigationView = findViewById(R.id.bottomNavigationView);
// 创建 Fragment 列表
List<Fragment> fragmentList = new ArrayList<>();
fragmentList.add(new NewsFragment());
fragmentList.add(new ImageFragment());
fragmentList.add(new ListFragment());
// 设置 ViewPager2 的适配器
ViewPagerAdapter adapter = new ViewPagerAdapter(this, fragmentList);
viewPager.setAdapter(adapter);
// 底部导航与 ViewPager2 联动
bottomNavigationView.setOnItemSelectedListener(item -> {
switch (item.getItemId()) {
case R.id.menu_news:
viewPager.setCurrentItem(0);
break;
case R.id.menu_image:
viewPager.setCurrentItem(1);
break;
case R.id.menu_list:
viewPager.setCurrentItem(2);
break;
}
return true;
});
// ViewPager2 滑动时更新底部导航选中状态
viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
switch (position) {
case 0:
bottomNavigationView.setSelectedItemId(R.id.menu_news);
break;
case 1:
bottomNavigationView.setSelectedItemId(R.id.menu_image);
break;
case 2:
bottomNavigationView.setSelectedItemId(R.id.menu_list);
break;
}
}
});
}
}
2. ViewPagerAdapter.java
package com.example.demo;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import java.util.List;
public class ViewPagerAdapter extends FragmentStateAdapter {
private final List<Fragment> fragmentList;
public ViewPagerAdapter(@NonNull FragmentActivity fragmentActivity, List<Fragment> fragmentList) {
super(fragmentActivity);
this.fragmentList = fragmentList;
}
@NonNull
@Override
public Fragment createFragment(int position) {
return fragmentList.get(position);
}
@Override
public int getItemCount() {
return fragmentList.size();
}
}
3. NewsFragment.java
package com.example.demo;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.List;
public class NewsFragment extends Fragment {
private RecyclerView recyclerView;
private MyAdapter adapter;
private List<ItemModel> itemList;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_news, container, false);
recyclerView = view.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
// 初始化数据
itemList = new ArrayList<>();
itemList.add(new ItemModel("Avatar 1", "News Title 1", "Content 1"));
itemList.add(new ItemModel("Avatar 2", "News Title 2", "Content 2"));
// 设置 Adapter
adapter = new MyAdapter(itemList, getContext());
recyclerView.setAdapter(adapter);
return view;
}
}
4. ImageFragment.java
package com.example.demo;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.List;
public class ImageFragment extends Fragment {
private RecyclerView recyclerView;
private MyAdapter adapter;
private List<ItemModel> itemList;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_image, container, false);
recyclerView = view.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 3)); // 3 列网格
// 初始化数据
itemList = new ArrayList<>();
itemList.add(new ItemModel("Avatar A", "Image Title 1", "Content 1"));
itemList.add(new ItemModel("Avatar B", "Image Title 2", "Content 2"));
// 设置 Adapter
adapter = new MyAdapter(itemList, getContext());
recyclerView.setAdapter(adapter);
return view;
}
}
5. ListFragment.java
package com.example.demo;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.List;
public class ListFragment extends Fragment {
private RecyclerView recyclerView;
private MyAdapter adapter;
private List<ItemModel> itemList;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_list, container, false);
recyclerView = view.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
// 初始化数据
itemList = new ArrayList<>();
itemList.add(new ItemModel("Avatar X", "List Title 1", "Content 1"));
itemList.add(new ItemModel("Avatar Y", "List Title 2", "Content 2"));
// 设置 Adapter
adapter = new MyAdapter(itemList, getContext());
recyclerView.setAdapter(adapter);
return view;
}
}
6. activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottomNavigationView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/windowBackground"
app:menu="@menu/bottom_navigation_menu" />
</LinearLayout>
7. bottom_navigation_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/menu_news"
android:icon="@drawable/ic_news"
android:title="News" />
<item
android:id="@+id/menu_image"
android:icon="@drawable/ic_image"
android:title="Images" />
<item
android:id="@+id/menu_list"
android:icon="@drawable/ic_list"
android:title="Lists" />
</menu>
8. fragment_news.xml / fragment_image.xml / fragment_list.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="8dp" />
</LinearLayout>
总结
- 底部导航联动:通过
BottomNavigationView
和ViewPager2
实现。 - 不同 Fragment 显示不同内容:每个
Fragment
使用RecyclerView
展示新闻、图片或列表。 - 数据展示:通过
RecyclerView
和自定义适配器完成。