From 7b87ef5f10fec18d7ddbceab2c73743fd936a1d4 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 5 Nov 2025 10:34:46 +0000 Subject: [PATCH] =?UTF-8?q?=E5=88=9B=E5=BB=BAAndroid=20MVVM=E6=9E=B6?= =?UTF-8?q?=E6=9E=84=E7=A4=BA=E4=BE=8B=E9=A1=B9=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增了一个完整的Android MVVM架构示例项目,包含: - Model层:User数据模型 - Repository层:UserRepository数据仓库 - ViewModel层:UserViewModel业务逻辑 - View层:MainActivity和UserAdapter - 使用LiveData实现响应式数据绑定 - RecyclerView展示用户列表 - Material Design UI组件 - 完整的Gradle配置和项目文档 --- android-mvvm-demo/README.md | 156 ++++++++++++++++++ android-mvvm-demo/app/build.gradle | 66 ++++++++ android-mvvm-demo/app/proguard-rules.pro | 25 +++ .../app/src/main/AndroidManifest.xml | 29 ++++ .../java/com/example/mvvmdemo/model/User.java | 63 +++++++ .../mvvmdemo/repository/UserRepository.java | 65 ++++++++ .../example/mvvmdemo/view/MainActivity.java | 91 ++++++++++ .../example/mvvmdemo/view/UserAdapter.java | 70 ++++++++ .../mvvmdemo/viewmodel/UserViewModel.java | 101 ++++++++++++ .../app/src/main/res/layout/activity_main.xml | 42 +++++ .../app/src/main/res/layout/item_user.xml | 46 ++++++ .../app/src/main/res/values/colors.xml | 10 ++ .../app/src/main/res/values/strings.xml | 8 + .../app/src/main/res/values/themes.xml | 17 ++ android-mvvm-demo/build.gradle | 21 +++ android-mvvm-demo/gradle.properties | 26 +++ android-mvvm-demo/settings.gradle | 18 ++ 17 files changed, 854 insertions(+) create mode 100644 android-mvvm-demo/README.md create mode 100644 android-mvvm-demo/app/build.gradle create mode 100644 android-mvvm-demo/app/proguard-rules.pro create mode 100644 android-mvvm-demo/app/src/main/AndroidManifest.xml create mode 100644 android-mvvm-demo/app/src/main/java/com/example/mvvmdemo/model/User.java create mode 100644 android-mvvm-demo/app/src/main/java/com/example/mvvmdemo/repository/UserRepository.java create mode 100644 android-mvvm-demo/app/src/main/java/com/example/mvvmdemo/view/MainActivity.java create mode 100644 android-mvvm-demo/app/src/main/java/com/example/mvvmdemo/view/UserAdapter.java create mode 100644 android-mvvm-demo/app/src/main/java/com/example/mvvmdemo/viewmodel/UserViewModel.java create mode 100644 android-mvvm-demo/app/src/main/res/layout/activity_main.xml create mode 100644 android-mvvm-demo/app/src/main/res/layout/item_user.xml create mode 100644 android-mvvm-demo/app/src/main/res/values/colors.xml create mode 100644 android-mvvm-demo/app/src/main/res/values/strings.xml create mode 100644 android-mvvm-demo/app/src/main/res/values/themes.xml create mode 100644 android-mvvm-demo/build.gradle create mode 100644 android-mvvm-demo/gradle.properties create mode 100644 android-mvvm-demo/settings.gradle diff --git a/android-mvvm-demo/README.md b/android-mvvm-demo/README.md new file mode 100644 index 00000000..eed92825 --- /dev/null +++ b/android-mvvm-demo/README.md @@ -0,0 +1,156 @@ +# Android MVVM 架构示例项目 + +这是一个使用 MVVM (Model-View-ViewModel) 架构模式的 Android 示例项目。 + +## 项目概述 + +本项目展示了如何在 Android 应用中实现 MVVM 架构,包括: +- Model: 数据模型 +- View: UI 层(Activity/Fragment) +- ViewModel: 业务逻辑层 +- Repository: 数据仓库层 + +## 技术栈 + +- **语言**: Java +- **最小 SDK**: 24 (Android 7.0) +- **目标 SDK**: 34 (Android 14) +- **架构**: MVVM (Model-View-ViewModel) +- **核心库**: + - AndroidX Lifecycle (ViewModel, LiveData) + - Material Components + - RecyclerView + - ConstraintLayout + +## 项目结构 + +``` +app/src/main/java/com/example/mvvmdemo/ +├── model/ # 数据模型 +│ └── User.java # 用户实体类 +├── repository/ # 数据仓库层 +│ └── UserRepository.java # 用户数据管理 +├── view/ # UI 层 +│ ├── MainActivity.java # 主界面 +│ └── UserAdapter.java # RecyclerView 适配器 +└── viewmodel/ # 业务逻辑层 + └── UserViewModel.java # 用户视图模型 +``` + +## MVVM 架构说明 + +### Model (模型层) +- **位置**: `model/User.java` +- **职责**: 定义数据结构和业务实体 +- **特点**: 纯数据类,不包含业务逻辑 + +### Repository (数据仓库层) +- **位置**: `repository/UserRepository.java` +- **职责**: 管理数据源,提供统一的数据访问接口 +- **特点**: + - 使用单例模式 + - 可以整合多个数据源(本地数据库、远程 API 等) + - 为 ViewModel 提供干净的数据访问 API + +### ViewModel (视图模型层) +- **位置**: `viewmodel/UserViewModel.java` +- **职责**: + - 处理业务逻辑 + - 管理 UI 相关数据 + - 通过 LiveData 向 View 提供数据 +- **特点**: + - 继承自 `androidx.lifecycle.ViewModel` + - 使用 LiveData 实现数据观察 + - 生命周期感知,配置更改时保持数据 + +### View (视图层) +- **位置**: `view/MainActivity.java`, `view/UserAdapter.java` +- **职责**: + - 显示 UI + - 处理用户交互 + - 观察 ViewModel 的数据变化 +- **特点**: + - 不包含业务逻辑 + - 通过观察 LiveData 更新 UI + - 通过 ViewModel 执行操作 + +## 数据流向 + +``` +View (用户操作) + ↓ +ViewModel (处理逻辑) + ↓ +Repository (获取数据) + ↓ +Model (数据实体) + ↓ +LiveData (通知变化) + ↓ +View (更新UI) +``` + +## 主要功能 + +1. **用户列表展示**: 使用 RecyclerView 显示用户列表 +2. **数据观察**: 通过 LiveData 实现响应式 UI 更新 +3. **刷新功能**: 点击 FAB 按钮刷新用户数据 +4. **Toast 消息**: 显示操作结果反馈 + +## 如何运行 + +1. 使用 Android Studio 打开项目 +2. 等待 Gradle 同步完成 +3. 连接 Android 设备或启动模拟器 +4. 点击 Run 按钮运行应用 + +## 构建项目 + +```bash +# 清理构建 +./gradlew clean + +# 构建 Debug 版本 +./gradlew assembleDebug + +# 构建 Release 版本 +./gradlew assembleRelease + +# 运行测试 +./gradlew test +``` + +## MVVM 架构的优势 + +1. **关注点分离**: 清晰的层次划分,各层职责明确 +2. **可测试性**: ViewModel 独立于 Android 组件,易于单元测试 +3. **生命周期感知**: ViewModel 在配置更改时保持数据 +4. **响应式编程**: 使用 LiveData 实现数据驱动 UI +5. **可维护性**: 代码结构清晰,易于维护和扩展 + +## 扩展建议 + +要进一步完善项目,可以考虑: + +1. **网络请求**: 集成 Retrofit 实现真实的 API 调用 +2. **本地存储**: 使用 Room 数据库持久化数据 +3. **依赖注入**: 使用 Dagger/Hilt 实现依赖注入 +4. **协程**: 使用 Kotlin Coroutines 处理异步操作 +5. **分页加载**: 使用 Paging 3 库实现列表分页 +6. **错误处理**: 完善错误处理和用户反馈机制 +7. **单元测试**: 为 ViewModel 和 Repository 编写单元测试 + +## 相关资源 + +- [Android Architecture Components](https://developer.android.com/topic/libraries/architecture) +- [LiveData](https://developer.android.com/topic/libraries/architecture/livedata) +- [ViewModel](https://developer.android.com/topic/libraries/architecture/viewmodel) +- [MVVM Pattern](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93viewmodel) + +## 许可证 + +MIT License + +## 作者 + +Android MVVM Demo Project diff --git a/android-mvvm-demo/app/build.gradle b/android-mvvm-demo/app/build.gradle new file mode 100644 index 00000000..56312677 --- /dev/null +++ b/android-mvvm-demo/app/build.gradle @@ -0,0 +1,66 @@ +plugins { + id 'com.android.application' +} + +android { + namespace 'com.example.mvvmdemo' + compileSdk 34 + + defaultConfig { + applicationId "com.example.mvvmdemo" + minSdk 24 + targetSdk 34 + 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_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + buildFeatures { + viewBinding true + } +} + +dependencies { + // AndroidX Core + implementation 'androidx.appcompat:appcompat:1.6.1' + implementation 'com.google.android.material:material:1.10.0' + implementation 'androidx.constraintlayout:constraintlayout:2.1.4' + + // Lifecycle components (ViewModel, LiveData) + implementation 'androidx.lifecycle:lifecycle-viewmodel:2.6.2' + implementation 'androidx.lifecycle:lifecycle-livedata:2.6.2' + implementation 'androidx.lifecycle:lifecycle-runtime:2.6.2' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' + + // RecyclerView + implementation 'androidx.recyclerview:recyclerview:1.3.2' + + // Retrofit for networking (optional) + implementation 'com.squareup.retrofit2:retrofit:2.9.0' + implementation 'com.squareup.retrofit2:converter-gson:2.9.0' + + // Coroutines for async operations + implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3' + + // Room Database (optional) + implementation 'androidx.room:room-runtime:2.6.0' + annotationProcessor 'androidx.room:room-compiler:2.6.0' + + // Testing + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.5' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' +} diff --git a/android-mvvm-demo/app/proguard-rules.pro b/android-mvvm-demo/app/proguard-rules.pro new file mode 100644 index 00000000..5bbb5155 --- /dev/null +++ b/android-mvvm-demo/app/proguard-rules.pro @@ -0,0 +1,25 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile + +# Keep MVVM classes +-keep class com.example.mvvmdemo.model.** { *; } +-keep class com.example.mvvmdemo.viewmodel.** { *; } diff --git a/android-mvvm-demo/app/src/main/AndroidManifest.xml b/android-mvvm-demo/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..3a389834 --- /dev/null +++ b/android-mvvm-demo/app/src/main/AndroidManifest.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + diff --git a/android-mvvm-demo/app/src/main/java/com/example/mvvmdemo/model/User.java b/android-mvvm-demo/app/src/main/java/com/example/mvvmdemo/model/User.java new file mode 100644 index 00000000..aa10429e --- /dev/null +++ b/android-mvvm-demo/app/src/main/java/com/example/mvvmdemo/model/User.java @@ -0,0 +1,63 @@ +package com.example.mvvmdemo.model; + +/** + * User Model class + * Represents a user entity in the MVVM architecture + */ +public class User { + private int id; + private String name; + private String email; + private String phone; + + public User(int id, String name, String email, String phone) { + this.id = id; + this.name = name; + this.email = email; + this.phone = phone; + } + + // Getters + public int getId() { + return id; + } + + public String getName() { + return name; + } + + public String getEmail() { + return email; + } + + public String getPhone() { + return phone; + } + + // Setters + public void setId(int id) { + this.id = id; + } + + public void setName(String name) { + this.name = name; + } + + public void setEmail(String email) { + this.email = email; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + @Override + public String toString() { + return "User{" + + "id=" + id + + ", name='" + name + '\'' + + ", email='" + email + '\'' + + ", phone='" + phone + '\'' + + '}'; + } +} diff --git a/android-mvvm-demo/app/src/main/java/com/example/mvvmdemo/repository/UserRepository.java b/android-mvvm-demo/app/src/main/java/com/example/mvvmdemo/repository/UserRepository.java new file mode 100644 index 00000000..10b143ff --- /dev/null +++ b/android-mvvm-demo/app/src/main/java/com/example/mvvmdemo/repository/UserRepository.java @@ -0,0 +1,65 @@ +package com.example.mvvmdemo.repository; + +import com.example.mvvmdemo.model.User; +import java.util.ArrayList; +import java.util.List; + +/** + * UserRepository class + * Manages data operations and provides a clean API for data access + * In a real app, this would interact with local database or remote API + */ +public class UserRepository { + + private static UserRepository instance; + + private UserRepository() { + // Private constructor for singleton pattern + } + + public static UserRepository getInstance() { + if (instance == null) { + instance = new UserRepository(); + } + return instance; + } + + /** + * Fetch users from data source + * In production, this would make API calls or database queries + */ + public List getUsers() { + // Simulating data fetch with dummy data + List users = new ArrayList<>(); + users.add(new User(1, "张三", "zhangsan@example.com", "13800138001")); + users.add(new User(2, "李四", "lisi@example.com", "13800138002")); + users.add(new User(3, "王五", "wangwu@example.com", "13800138003")); + users.add(new User(4, "赵六", "zhaoliu@example.com", "13800138004")); + users.add(new User(5, "钱七", "qianqi@example.com", "13800138005")); + return users; + } + + /** + * Add a new user + */ + public boolean addUser(User user) { + // In production, save to database or send to API + return true; + } + + /** + * Delete a user + */ + public boolean deleteUser(int userId) { + // In production, delete from database or API + return true; + } + + /** + * Update user information + */ + public boolean updateUser(User user) { + // In production, update in database or API + return true; + } +} diff --git a/android-mvvm-demo/app/src/main/java/com/example/mvvmdemo/view/MainActivity.java b/android-mvvm-demo/app/src/main/java/com/example/mvvmdemo/view/MainActivity.java new file mode 100644 index 00000000..4f33ccb9 --- /dev/null +++ b/android-mvvm-demo/app/src/main/java/com/example/mvvmdemo/view/MainActivity.java @@ -0,0 +1,91 @@ +package com.example.mvvmdemo.view; + +import android.os.Bundle; +import android.view.View; +import android.widget.Toast; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.lifecycle.Observer; +import androidx.lifecycle.ViewModelProvider; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.example.mvvmdemo.R; +import com.example.mvvmdemo.model.User; +import com.example.mvvmdemo.viewmodel.UserViewModel; +import com.google.android.material.floatingactionbutton.FloatingActionButton; + +import java.util.List; + +/** + * MainActivity - View layer + * Displays user list using RecyclerView + * Observes ViewModel for data changes + */ +public class MainActivity extends AppCompatActivity { + + private UserViewModel userViewModel; + private RecyclerView recyclerView; + private UserAdapter userAdapter; + private FloatingActionButton fabRefresh; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + // Initialize ViewModel + userViewModel = new ViewModelProvider(this).get(UserViewModel.class); + + // Setup RecyclerView + setupRecyclerView(); + + // Setup UI components + setupUI(); + + // Observe LiveData from ViewModel + observeViewModel(); + + // Load initial data + userViewModel.loadUsers(); + } + + private void setupRecyclerView() { + recyclerView = findViewById(R.id.recyclerView); + recyclerView.setLayoutManager(new LinearLayoutManager(this)); + userAdapter = new UserAdapter(); + recyclerView.setAdapter(userAdapter); + } + + private void setupUI() { + fabRefresh = findViewById(R.id.fabRefresh); + fabRefresh.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + userViewModel.refreshUsers(); + } + }); + } + + private void observeViewModel() { + // Observe users list + userViewModel.getUsersLiveData().observe(this, new Observer>() { + @Override + public void onChanged(List users) { + if (users != null) { + userAdapter.setUsers(users); + } + } + }); + + // Observe messages + userViewModel.getMessageLiveData().observe(this, new Observer() { + @Override + public void onChanged(String message) { + if (message != null && !message.isEmpty()) { + Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show(); + } + } + }); + } +} diff --git a/android-mvvm-demo/app/src/main/java/com/example/mvvmdemo/view/UserAdapter.java b/android-mvvm-demo/app/src/main/java/com/example/mvvmdemo/view/UserAdapter.java new file mode 100644 index 00000000..e02022b6 --- /dev/null +++ b/android-mvvm-demo/app/src/main/java/com/example/mvvmdemo/view/UserAdapter.java @@ -0,0 +1,70 @@ +package com.example.mvvmdemo.view; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.example.mvvmdemo.R; +import com.example.mvvmdemo.model.User; + +import java.util.ArrayList; +import java.util.List; + +/** + * UserAdapter for RecyclerView + * Displays user list items + */ +public class UserAdapter extends RecyclerView.Adapter { + + private List users = new ArrayList<>(); + + @NonNull + @Override + public UserViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.item_user, parent, false); + return new UserViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull UserViewHolder holder, int position) { + User user = users.get(position); + holder.bind(user); + } + + @Override + public int getItemCount() { + return users.size(); + } + + public void setUsers(List users) { + this.users = users; + notifyDataSetChanged(); + } + + /** + * ViewHolder for user items + */ + static class UserViewHolder extends RecyclerView.ViewHolder { + private TextView tvName; + private TextView tvEmail; + private TextView tvPhone; + + public UserViewHolder(@NonNull View itemView) { + super(itemView); + tvName = itemView.findViewById(R.id.tvName); + tvEmail = itemView.findViewById(R.id.tvEmail); + tvPhone = itemView.findViewById(R.id.tvPhone); + } + + public void bind(User user) { + tvName.setText(user.getName()); + tvEmail.setText(user.getEmail()); + tvPhone.setText(user.getPhone()); + } + } +} diff --git a/android-mvvm-demo/app/src/main/java/com/example/mvvmdemo/viewmodel/UserViewModel.java b/android-mvvm-demo/app/src/main/java/com/example/mvvmdemo/viewmodel/UserViewModel.java new file mode 100644 index 00000000..74c3e148 --- /dev/null +++ b/android-mvvm-demo/app/src/main/java/com/example/mvvmdemo/viewmodel/UserViewModel.java @@ -0,0 +1,101 @@ +package com.example.mvvmdemo.viewmodel; + +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.ViewModel; + +import com.example.mvvmdemo.model.User; +import com.example.mvvmdemo.repository.UserRepository; + +import java.util.List; + +/** + * UserViewModel class + * Acts as a bridge between the View and Model + * Manages UI-related data and business logic + */ +public class UserViewModel extends ViewModel { + + private UserRepository userRepository; + private MutableLiveData> usersLiveData; + private MutableLiveData messageLiveData; + + public UserViewModel() { + userRepository = UserRepository.getInstance(); + usersLiveData = new MutableLiveData<>(); + messageLiveData = new MutableLiveData<>(); + } + + /** + * Get LiveData for users list + */ + public LiveData> getUsersLiveData() { + return usersLiveData; + } + + /** + * Get LiveData for messages + */ + public LiveData getMessageLiveData() { + return messageLiveData; + } + + /** + * Load users from repository + */ + public void loadUsers() { + // In production, this would be done asynchronously + // using Coroutines, RxJava, or AsyncTask + List users = userRepository.getUsers(); + usersLiveData.setValue(users); + messageLiveData.setValue("成功加载 " + users.size() + " 个用户"); + } + + /** + * Add a new user + */ + public void addUser(String name, String email, String phone) { + int newId = (usersLiveData.getValue() != null) + ? usersLiveData.getValue().size() + 1 + : 1; + + User newUser = new User(newId, name, email, phone); + boolean success = userRepository.addUser(newUser); + + if (success) { + // Reload users to update the list + loadUsers(); + messageLiveData.setValue("用户添加成功"); + } else { + messageLiveData.setValue("用户添加失败"); + } + } + + /** + * Delete a user + */ + public void deleteUser(int userId) { + boolean success = userRepository.deleteUser(userId); + + if (success) { + loadUsers(); + messageLiveData.setValue("用户删除成功"); + } else { + messageLiveData.setValue("用户删除失败"); + } + } + + /** + * Refresh user data + */ + public void refreshUsers() { + messageLiveData.setValue("刷新中..."); + loadUsers(); + } + + @Override + protected void onCleared() { + super.onCleared(); + // Clean up resources if needed + } +} diff --git a/android-mvvm-demo/app/src/main/res/layout/activity_main.xml b/android-mvvm-demo/app/src/main/res/layout/activity_main.xml new file mode 100644 index 00000000..1087fd11 --- /dev/null +++ b/android-mvvm-demo/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + diff --git a/android-mvvm-demo/app/src/main/res/layout/item_user.xml b/android-mvvm-demo/app/src/main/res/layout/item_user.xml new file mode 100644 index 00000000..b75ba32c --- /dev/null +++ b/android-mvvm-demo/app/src/main/res/layout/item_user.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + diff --git a/android-mvvm-demo/app/src/main/res/values/colors.xml b/android-mvvm-demo/app/src/main/res/values/colors.xml new file mode 100644 index 00000000..ca1931bc --- /dev/null +++ b/android-mvvm-demo/app/src/main/res/values/colors.xml @@ -0,0 +1,10 @@ + + + #FFBB86FC + #FF6200EE + #FF3700B3 + #FF03DAC5 + #FF018786 + #FF000000 + #FFFFFFFF + diff --git a/android-mvvm-demo/app/src/main/res/values/strings.xml b/android-mvvm-demo/app/src/main/res/values/strings.xml new file mode 100644 index 00000000..8e2df9e1 --- /dev/null +++ b/android-mvvm-demo/app/src/main/res/values/strings.xml @@ -0,0 +1,8 @@ + + + MVVM Demo + 刷新 + 加载中... + 错误 + 暂无数据 + diff --git a/android-mvvm-demo/app/src/main/res/values/themes.xml b/android-mvvm-demo/app/src/main/res/values/themes.xml new file mode 100644 index 00000000..6c701ccf --- /dev/null +++ b/android-mvvm-demo/app/src/main/res/values/themes.xml @@ -0,0 +1,17 @@ + + + + + diff --git a/android-mvvm-demo/build.gradle b/android-mvvm-demo/build.gradle new file mode 100644 index 00000000..263a4c12 --- /dev/null +++ b/android-mvvm-demo/build.gradle @@ -0,0 +1,21 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +buildscript { + repositories { + google() + mavenCentral() + } + dependencies { + classpath 'com.android.tools.build:gradle:8.1.0' + } +} + +allprojects { + repositories { + google() + mavenCentral() + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/android-mvvm-demo/gradle.properties b/android-mvvm-demo/gradle.properties new file mode 100644 index 00000000..fc38adb0 --- /dev/null +++ b/android-mvvm-demo/gradle.properties @@ -0,0 +1,26 @@ +# Project-wide Gradle settings. +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. + +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html + +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 + +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true + +# AndroidX package structure to make it clearer which packages are bundled with the +# Android operating system, and which are packaged with your app's APK +# https://developer.android.com/topic/libraries/support-library/androidx-rn +android.useAndroidX=true + +# Enables namespacing of each library's R class so that its R class includes only the +# resources declared in the library itself and none from the library's dependencies, +# thereby reducing the size of the R class for that library +android.nonTransitiveRClass=true diff --git a/android-mvvm-demo/settings.gradle b/android-mvvm-demo/settings.gradle new file mode 100644 index 00000000..79de8add --- /dev/null +++ b/android-mvvm-demo/settings.gradle @@ -0,0 +1,18 @@ +pluginManagement { + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} + +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + google() + mavenCentral() + } +} + +rootProject.name = "MVVM Demo" +include ':app'