安卓应用开发学习:应用ViewPager2翻页视图实现页面水平切换

一、引言

我的第一款安卓app是在2022年开发的,旨在解决公司员工在室外工作环境下,进行某个专项工作时,数据处理不方便的问题。当时我并不会安卓应用的开发,是在边学边练的过程中完成了这款软件。软件投入使用后,效果不错,得到了同事们的赞许,也得到了上级领导的肯定。一晃已经过了三年,这期间我们公司的相关工作也发生了一些变化,同事们也会提出一些改进需求,我也根据需求对这款软件进行了两次升级。最近,公司的相关工作又有变动,为了适应新的需求,这款软件再次面临升级。

由于软件要实现的功能并不复杂,因此,之前的版本都是单页面的,可随着新增加的内容越来越多,我感觉还继续用单页面有些不合适了。这次升级又要添加新的内容,我便打算将之前的单页拆分成多页,并能像微信、淘宝一样支持左右水平翻页。

二、开发需求

对原有软件进行升级,将原有的功能模块从单页面变为两个独立的页面以应对两个不同的工作场景,再增加一个页面用于本次升级需要新增的一个工作场景。升级后的app由三个页面组成,每个页面对应一种工作场景,且三个页面能通过水平滑动进行切换。

三个页面的相似度比较高,但有所不同,其中第三个页面,页面布局变动会多一点,且其逻辑运算部分也要重新编写。

数据运算逻辑方面不是大问题,只需要对以前的代码进行修改就可以实现新的功能,比较麻烦的是软件界面的变化比较大,结构发生了根本性变化,相关的代码基本要重新写了。

三、借助DeepSeek开发软件

以前阅读安卓软件开发书籍的时候,我知晓了翻页视图可以实现页面的切换,但我还没有在开发中应用过,这次正好实践一下。刚开始,我是准备照着书籍上的内容用第一代翻页视图ViewPager开发软件的,但刚一开始就发现,Android Studio中提示第一代翻页视图ViewPager已经被弃用了。而教材上关于第二代翻页视图ViewPager2的内容写得没有第一代翻页视图详细,我不太愿意花大量时间去研读,干脆讲这个问题交给DeepSeek解决吧。

我将自己的需求发给DeepSeek。

经过不到一分钟的思考,DeepSeek给了我一份很详细的解决方案,并附有一个完整的示例。有了这个示例,我的软件开发就容易很多了。以下内容是DeepSeek提供给我的:

下面是一个完整的示例,展示了如何使用ViewPager2和TabLayout创建一个具有三个不同功能页面的安卓应用。

步骤1:添加依赖项

首先,在build.gradle(Module: app)文件中添加所需依赖:

java 复制代码
dependencies {
    implementation 'androidx.appcompat:appcompat:1.4.1'
    implementation 'com.google.android.material:material:1.5.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
    implementation 'androidx.viewpager2:viewpager2:1.0.0'
}
步骤2:创建主布局文件 (activity_main.xml)
XML 复制代码
<?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:tabMode="fixed"
        app:tabGravity="fill" />

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/viewPager2"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />
</LinearLayout>
步骤3:创建三个Fragment及其布局

页面1:BMI计算器 (fragment_bmi.xml)

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"
    android:padding="16dp">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="BMI计算器"
        android:textSize="20sp"
        android:textStyle="bold"
        android:gravity="center"
        android:layout_marginBottom="20dp" />

    <EditText
        android:id="@+id/etWeight"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入体重(kg)"
        android:inputType="numberDecimal" />

    <EditText
        android:id="@+id/etHeight"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入身高(m)"
        android:inputType="numberDecimal"
        android:layout_marginTop="10dp" />

    <Button
        android:id="@+id/btnCalculate"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="计算BMI"
        android:layout_marginTop="20dp" />

    <TextView
        android:id="@+id/tvResult"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:textSize="18sp"
        android:gravity="center" />
</LinearLayout>

页面2:货币转换器 (fragment_currency.xml)

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"
    android:padding="16dp">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="货币转换器(USD to CNY)"
        android:textSize="20sp"
        android:textStyle="bold"
        android:gravity="center"
        android:layout_marginBottom="20dp" />

    <EditText
        android:id="@+id/etUsd"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入美元金额"
        android:inputType="numberDecimal" />

    <Button
        android:id="@+id/btnConvert"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="转换"
        android:layout_marginTop="20dp" />

    <TextView
        android:id="@+id/tvCurrencyResult"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:textSize="18sp"
        android:gravity="center" />
</LinearLayout>

页面3:简单数学计算 (fragment_math.xml)

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"
    android:padding="16dp">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="简单数学计算"
        android:textSize="20sp"
        android:textStyle="bold"
        android:gravity="center"
        android:layout_marginBottom="20dp" />

    <EditText
        android:id="@+id/etNum1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入第一个数字"
        android:inputType="numberDecimal" />

    <EditText
        android:id="@+id/etNum2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入第二个数字"
        android:inputType="numberDecimal"
        android:layout_marginTop="10dp" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_marginTop="10dp">

        <Button
            android:id="@+id/btnAdd"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="加法" />

        <Button
            android:id="@+id/btnSubtract"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="减法" />

    </LinearLayout>

    <TextView
        android:id="@+id/tvMathResult"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:textSize="18sp"
        android:gravity="center" />
</LinearLayout>
步骤4:创建Fragment类

BMIFragment.java

java 复制代码
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import androidx.fragment.app.Fragment;
public class BMIFragment extends Fragment {

    private EditText etWeight, etHeight;
    private Button btnCalculate;
    private TextView tvResult;

    public BMIFragment() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_bmi, container, false);
        
        etWeight = view.findViewById(R.id.etWeight);
        etHeight = view.findViewById(R.id.etHeight);
        btnCalculate = view.findViewById(R.id.btnCalculate);
        tvResult = view.findViewById(R.id.tvResult);
        
        btnCalculate.setOnClickListener(v -> calculateBMI());
        
        return view;
    }
    
    private void calculateBMI() {
        String weightStr = etWeight.getText().toString();
        String heightStr = etHeight.getText().toString();
        
        if (weightStr.isEmpty() || heightStr.isEmpty()) {
            tvResult.setText("请输入体重和身高");
            return;
        }
        
        float weight = Float.parseFloat(weightStr);
        float height = Float.parseFloat(heightStr);
        
        if (height <= 0 || weight <= 0) {
            tvResult.setText("请输入有效的体重和身高");
            return;
        }
        
        float bmi = weight / (height * height);
        String result = String.format("您的BMI指数: %.2f\n", bmi);
        
        if (bmi < 18.5) {
            result += "体重过轻";
        } else if (bmi < 24) {
            result += "正常范围";
        } else if (bmi < 28) {
            result += "超重";
        } else {
            result += "肥胖";
        }
        
        tvResult.setText(result);
}}

CurrencyFragment.java

java 复制代码
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import androidx.fragment.app.Fragment;
public class CurrencyFragment extends Fragment {

    private EditText etUsd;
    private Button btnConvert;
    private TextView tvCurrencyResult;

    public CurrencyFragment() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_currency, container, false);
        
        etUsd = view.findViewById(R.id.etUsd);
        btnConvert = view.findViewById(R.id.btnConvert);
        tvCurrencyResult = view.findViewById(R.id.tvCurrencyResult);
        
        btnConvert.setOnClickListener(v -> convertCurrency());
        
        return view;
    }
    
    private void convertCurrency() {
        String usdStr = etUsd.getText().toString();
        
        if (usdStr.isEmpty()) {
            tvCurrencyResult.setText("请输入美元金额");
            return;
        }
        
        float usd = Float.parseFloat(usdStr);
        
        if (usd <= 0) {
            tvCurrencyResult.setText("请输入有效的金额");
            return;
        }
        
        // 假设汇率为 1 USD = 6.5 CNY
        float cny = usd * 6.5f;
        String result = String.format("%.2f 美元 = %.2f 人民币", usd, cny);
        
        tvCurrencyResult.setText(result);
}}

MathFragment.java

java 复制代码
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import androidx.fragment.app.Fragment;
public class MathFragment extends Fragment {

    private EditText etNum1, etNum2;
    private Button btnAdd, btnSubtract;
    private TextView tvMathResult;

    public MathFragment() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_math, container, false);
        
        etNum1 = view.findViewById(R.id.etNum1);
        etNum2 = view.findViewById(R.id.etNum2);
        btnAdd = view.findViewById(R.id.btnAdd);
        btnSubtract = view.findViewById(R.id.btnSubtract);
        tvMathResult = view.findViewById(R.id.tvMathResult);
        
        btnAdd.setOnClickListener(v -> calculate('+'));
        btnSubtract.setOnClickListener(v -> calculate('-'));
        
        return view;
    }
    
    private void calculate(char operator) {
        String num1Str = etNum1.getText().toString();
        String num2Str = etNum2.getText().toString();
        
        if (num1Str.isEmpty() || num2Str.isEmpty()) {
            tvMathResult.setText("请输入两个数字");
            return;
        }
        
        float num1 = Float.parseFloat(num1Str);
        float num2 = Float.parseFloat(num2Str);
        float result = 0;
        
        switch (operator) {
            case '+':
                result = num1 + num2;
                break;
            case '-':
                result = num1 - num2;
                break;
        }
        
        String operation = (operator == '+') ? "加法" : "减法";
        String output = String.format("%s结果: %.2f", operation, result);
        
        tvMathResult.setText(output);
}}
步骤5:创建ViewPager2适配器

ViewPagerAdapter.java

java 复制代码
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter;
public class ViewPagerAdapter extends FragmentStateAdapter {

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

    @NonNull
    @Override
    public Fragment createFragment(int position) {
        switch (position) {
            case 0:
                return new BMIFragment();
            case 1:
                return new CurrencyFragment();
            case 2:
                return new MathFragment();
            default:
                return new BMIFragment();
        }
    }

    @Override
    public int getItemCount() {
        return 3;
}}
步骤6:设置主Activity

MainActivity.java

java 复制代码
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.widget.ViewPager2;
import android.os.Bundle;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
public class MainActivity extends AppCompatActivity {

    private ViewPager2 viewPager2;
    private TabLayout tabLayout;

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

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

        // 设置ViewPager2适配器
        ViewPagerAdapter adapter = new ViewPagerAdapter(this);
        viewPager2.setAdapter(adapter);

        // 关联TabLayout和ViewPager2
        new TabLayoutMediator(tabLayout, viewPager2,
                (tab, position) -> {
                    switch (position) {
                        case 0:
                            tab.setText("BMI计算");
                            break;
                        case 1:
                            tab.setText("货币转换");
                            break;
                        case 2:
                            tab.setText("数学计算");
                            break;
                    }
                }).attach();
}}
总结

这个示例展示了如何使用ViewPager2和TabLayout创建一个具有三个不同功能页面的安卓应用:

1. BMI计算器 :计算身体质量指数

2. 货币转换器 :将美元转换为人民币

3. 简单数学计算 :执行加法和减法运算

每个Fragment都有独立的布局和功能逻辑,ViewPager2负责管理页面切换,TabLayout提供标签导航。你可以根据需要修改每个页面的功能和样式。

记得在AndroidManifest.xml中设置适当的权限和屏幕方向(如果需要)。

四、成果展示

借助DeepSeek提供的示例,我很顺利了搞定了翻页视图。三个页面看上去相似,但实现功能有所不同,使用到的同事也不同,以前可以设计在一个页面,现在新增加功能后,再设计在一个页面,会导致组件数增多,显示的内容会超出屏幕范围。因此,本次根据具体的业务,设计成了三个页面,不同的业务使用不同的页面即可。

相关推荐
驱动起爆大师x_x2 小时前
CAN总线的数据采样和同步问题
stm32·嵌入式硬件·学习·can
tingting01192 小时前
mysql 8.4.2 备份脚本
android·数据库·mysql
William_cl2 小时前
【连载1】《假装自己是个小白 —— 重新认识 MySQL》实践指南
android·mysql·oracle
脚踏实地,坚持不懈!2 小时前
Android,jetpack compose实现俄罗斯方块,简单案例♦️
android
charlie1145141913 小时前
精读C++20设计模式——创造型设计模式:单例模式
c++·学习·单例模式·设计模式·c++20
一直向钱3 小时前
android 字符串工具类(兼容 Android 16+ / API 16,无报错版)
android
leo_yu_yty4 小时前
Mysql DBA学习笔记(主从复制)
学习·mysql·dba
AganTee4 小时前
deepseek 电脑端怎么下载?网页版与本地部署教程
ai·deepseek