Android 实现首页Tab切换并且支持懒加载功能详解

目录

    • [1. 添加依赖](#1. 添加依赖)
    • [2. 布局文件](#2. 布局文件)
    • [3. 创建 Fragment](#3. 创建 Fragment)
    • [4. 创建适配器](#4. 创建适配器)
    • [5. 在 MainActivity 中设置 TabLayout 和 ViewPager2](#5. 在 MainActivity 中设置 TabLayout 和 ViewPager2)

1. 添加依赖

在 build.gradle 文件中添加以下依赖:

bash 复制代码
implementation 'androidx.viewpager2:viewpager2:1.1.0-beta01'
implementation 'com.google.android.material:material:1.6.1'

2. 布局文件

在 res/layout/activity_main.xml 中创建主界面布局:

bash 复制代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tabLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabGravity="fill"
        app:tabMode="fixed" />

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/viewPager2"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

3. 创建 Fragment

创建多个 Fragment 用于展示不同的页面内容,以 HomeFragment 为例:

bash 复制代码
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

public class HomeFragment extends Fragment {

    private boolean isLoaded = false;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_home, container, false);
    }

    @Override
    public void onResume() {
        super.onResume();
        if (!isLoaded && isVisible()) {
            loadData();
            isLoaded = true;
        }
    }

    private void loadData() {
        // 这里进行数据加载操作,例如网络请求等
    }
}

对应的 fragment_home.xml 布局文件:

bash 复制代码
<?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:gravity="center"
    android:orientation="vertical">

    <TextView
        android:text="Home Page"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="24sp" />
</LinearLayout>

4. 创建适配器

创建一个继承自 FragmentStateAdapter 的适配器类:

bash 复制代码
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter;

import java.util.ArrayList;
import java.util.List;

public class MyFragmentStateAdapter extends FragmentStateAdapter {

    private final List<Fragment> fragmentList = new ArrayList<>();

    public MyFragmentStateAdapter(@NonNull FragmentActivity fragmentActivity) {
        super(fragmentActivity);
    }

    public void addFragment(Fragment fragment) {
        fragmentList.add(fragment);
    }

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

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

5. 在 MainActivity 中设置 TabLayout 和 ViewPager2

bash 复制代码
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.widget.ViewPager2;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
import android.os.Bundle;
import android.graphics.drawable.Drawable;
import androidx.core.content.ContextCompat;

public class MainActivity extends AppCompatActivity {

    private TabLayout tabLayout;
    private ViewPager2 viewPager2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tabLayout = findViewById(R.id.tabLayout);
        viewPager2 = findViewById(R.id.viewPager2);

        MyFragmentStateAdapter adapter = new MyFragmentStateAdapter(this);
        adapter.addFragment(new HomeFragment());
        adapter.addFragment(new DiscoverFragment());
        adapter.addFragment(new ProfileFragment());

        viewPager2.setAdapter(adapter);

        new TabLayoutMediator(tabLayout, viewPager2, (tab, position) -> {
            switch (position) {
                case 0:
                    tab.setText("Home");
                    Drawable homeIcon = ContextCompat.getDrawable(this, R.drawable.ic_home);
                    tab.setIcon(homeIcon);
                    break;
                case 1:
                    tab.setText("Discover");
                    Drawable discoverIcon = ContextCompat.getDrawable(this, R.drawable.ic_discover);
                    tab.setIcon(discoverIcon);
                    break;
                case 2:
                    tab.setText("Profile");
                    Drawable profileIcon = ContextCompat.getDrawable(this, R.drawable.ic_profile);
                    tab.setIcon(profileIcon);
                    break;
            }
        }).attach();
    }
}

运行该应用后,你会看到一个带有图片和文字的 TabLayout,同时可以通过点击 Tab 或者左右滑动屏幕来切换不同的页面,并且每个 Fragment 会在第一次可见时进行数据加载,实现了懒加载的功能。

相关推荐
程序员陆业聪5 小时前
从 OpenClaw 到 Android:Harness Engineering 是怎么让 Agent 变得可用的
android
hnlgzb7 小时前
常见的Android Jetpack库会有哪些?这些库中又有哪些常用类的?
android·android jetpack
钛态10 小时前
Flutter 三方库 http_mock_adapter — 赋能鸿蒙应用开发的高效率网络接口 Mock 与自动化测试注入引擎(适配鸿蒙 HarmonyOS Next ohos)
android·网络协议·flutter·http·华为·中间件·harmonyos
王码码203510 小时前
Flutter for OpenHarmony:Flutter 三方库 algoliasearch 毫秒级云端搜索体验(云原生搜索引擎)
android·前端·git·flutter·搜索引擎·云原生·harmonyos
左手厨刀右手茼蒿10 小时前
Flutter for OpenHarmony: Flutter 三方库 shamsi_date 助力鸿蒙应用精准适配波斯历法(中东出海必备)
android·flutter·ui·华为·自动化·harmonyos
代码飞天10 小时前
wireshark的高级使用
android·java·wireshark
2501_9159184111 小时前
苹果App Store上架审核卡住原因分析与解决方案指南
android·ios·小程序·https·uni-app·iphone·webview
skiy11 小时前
MySQL Workbench菜单汉化为中文
android·数据库·mysql
小小小点12 小时前
Android四大常用布局详解与实战
android
MinQ13 小时前
binder和socket区别及原理
android