feat: migrate to MVVM architecture with ViewBinding

- Replace old MainActivity with MVVM structure
- Add MainViewModel for business logic separation
- Implement ViewBinding for type-safe UI access
- Move MainActivity to ui.main package
- Remove Kotlin DSL files (build.gradle.kts, settings.gradle.kts)
- Add Chinese localization support

This refactoring improves code maintainability, testability, and follows modern Android development standards.
main
Yangk 3 weeks ago
parent 9707314aee
commit 28b432159f

@ -0,0 +1,39 @@
plugins {
alias(libs.plugins.android.application)
}
android {
namespace 'com.example.mobile_pda'
compileSdk 36
defaultConfig {
applicationId "com.example.mobile_pda"
minSdk 26
targetSdk 36
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
}
dependencies {
implementation libs.appcompat
implementation libs.material
implementation libs.activity
implementation libs.constraintlayout
testImplementation libs.junit
androidTestImplementation libs.ext.junit
androidTestImplementation libs.espresso.core
}

@ -0,0 +1,67 @@
package com.example.mobile_pda.ui.main;
import android.os.Bundle;
import android.widget.Toast;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModelProvider;
import com.example.mobile_pda.R;
import com.example.mobile_pda.databinding.ActivityMainBinding;
public class MainActivity extends AppCompatActivity {
private ActivityMainBinding binding;
private MainViewModel viewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
// 1. 使用 ViewBinding 极简初始化,淘汰 findViewById
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
// 2. 初始化 ViewModel状态隔离
viewModel = new ViewModelProvider(this).get(MainViewModel.class);
setupObservers();
setupListeners();
}
private void setupObservers() {
// 观察运行状态的变化
viewModel.getIsRunning().observe(this, isRunning -> {
if (isRunning) {
// UI状态随着数据改变只是模拟示例
binding.btnStartHeader.setEnabled(false);
binding.btnPauseHeader.setEnabled(true);
} else {
binding.btnStartHeader.setEnabled(true);
binding.btnPauseHeader.setEnabled(false);
}
});
}
private void setupListeners() {
// 使用 Binding 直接访问控件
binding.btnActionStart.setOnClickListener(v -> {
Toast.makeText(this, getString(R.string.toast_start_clicked), Toast.LENGTH_SHORT).show();
viewModel.startOperation();
});
binding.btnActionFinish.setOnClickListener(v -> {
Toast.makeText(this, getString(R.string.toast_finish_clicked), Toast.LENGTH_SHORT).show();
viewModel.finishOperation();
});
}
@Override
protected void onDestroy() {
super.onDestroy();
// 清理 binding 引用防止内存泄漏
binding = null;
}
}

@ -0,0 +1,23 @@
package com.example.mobile_pda.ui.main;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
public class MainViewModel extends ViewModel {
// 模拟的业务运行状态LiveData实现生命周期感知
private final MutableLiveData<Boolean> isRunning = new MutableLiveData<>(false);
public LiveData<Boolean> getIsRunning() {
return isRunning;
}
public void startOperation() {
isRunning.setValue(true);
}
public void finishOperation() {
isRunning.setValue(false);
}
}

@ -0,0 +1,4 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
alias(libs.plugins.android.application) apply false
}

@ -0,0 +1,23 @@
pluginManagement {
repositories {
google {
content {
includeGroupByRegex("com\\.android.*")
includeGroupByRegex("com\\.google.*")
includeGroupByRegex("androidx.*")
}
}
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}
rootProject.name = "Mobile_PDA"
include ':app'
Loading…
Cancel
Save