《Android 应用开发基础教程》——第七章:多页面组件结合实践:ViewPager2 与 Fragment 的联动

目录

第七章:多页面组件结合实践:ViewPager2 与 Fragment 的联动

📖 7.1 ViewPager2 简介

📦 7.2 准备工作

☑ 添加依赖(通常已默认)

☑ 布局文件 activity_main.xml

📚 7.3 创建多个 Fragment 页面

☑ 示例:创建三个 Fragment(PageOneFragment、PageTwoFragment、PageThreeFragment)

🔄 7.4 ViewPager2 配合 FragmentAdapter

☑ 在 MainActivity.java 中绑定适配器:

🎯 7.5 TabLayout 联动(附加功能)

☑ 添加 TabLayout 依赖

☑ 修改布局文件

☑ 联动代码(在 MainActivity 中):

📌 本章小结

🧪 实战练习

习题答案

项目结构

1. MainActivity.java

2. ViewPagerAdapter.java

3. NewsFragment.java

4. ImageFragment.java

5. ListFragment.java

6. activity_main.xml

7. bottom_navigation_menu.xml

8. fragment_news.xml / fragment_image.xml / fragment_list.xml

总结


第七章:多页面组件结合实践:ViewPager2 与 Fragment 的联动

📖 7.1 ViewPager2 简介

ViewPager2ViewPager 的升级版,用于滑动切换页面,常用于多页面布局,如首页、功能页、我的界面等。

特点:

  • 支持垂直和水平滑动

  • 原生支持 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 优化

🧪 实战练习

  1. 添加底部导航(BottomNavigationView)与 ViewPager2 联动

  2. 让每个 Fragment 显示不同内容:如新闻、图片、列表

  3. 在 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>

总结

  1. 底部导航联动:通过 BottomNavigationView 和 ViewPager2 实现。
  2. 不同 Fragment 显示不同内容:每个 Fragment 使用 RecyclerView 展示新闻、图片或列表。
  3. 数据展示:通过 RecyclerView 和自定义适配器完成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WenJGo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值