当前位置: 首页 > news >正文

Android架构模式推荐及分析和MVC架构模式制作一个简单的底部tab切换

目录

主流架构模式对比

适用场景

MVP‌:团队协作开发,需要高可测试性的项目

MVC架构模式制作一个简单的底部tab切换

(Model-View-Controller)结构

代码 

效果


主流架构模式对比

对比维度MVC‌ MVP‌ MVVM‌ MVI‌ 
学习曲线最低(基础分层清晰)中等(需接口抽象)较高(依赖数据绑定框架)最高(状态流管理复杂)
代码复杂度低(但易导致Controller臃肿)中等(分层明确)高(双向绑定调试难度大)极高(单向数据流逻辑严密)
可测试性差(业务与UI耦合)优秀(Presenter独立测试)良好(ViewModel可单元测试)优秀(状态隔离测试友好)
适用项目规模小型原型项目(<10个页面)中小型项目(10-50个页面)中大型项目(50+页面)高交互复杂项目(如金融交易)
使用率传统项目遗留较多(约25%)企业级应用常见(约35%)主流框架推荐(约40%)新兴趋势上升(约15%)
  • 小型简单项目‌:优先选择MVC,Android自带支持无需额外架构代码
  • 中型交互项目‌:MVVM通过数据绑定技术可减少约40%的UI同步代码
  • 测试驱动开发‌:MVP虽代码量较多但分层更清晰,便于单元测试

适用场景

  1. MVC‌:原生支持无需额外框架,推荐用于教学演示或超简易工具类App开发 
  2. MVP‌:团队协作开发,需要高可测试性的项目
  3. MVVM‌:响应式编程模式,适合长期维护的中大型项目(需搭配DataBinding或Jetpack Compose)
  4. MVI‌:适用于强状态管理需求(如实时聊天、股票交易系统)

MVC架构模式制作一个简单的底部tab切换

(Model-View-Controller)结构

src/
├── main/
│   ├── java/com/ys/autoapp/
│   │   ├── MainActivity.java        <-- Controller(主控制逻辑)
│   │   ├── HomeFragment.java        <-- Controller(首页页面逻辑)
│   │   ├── RulesFragment.java       <-- Controller(规则页面逻辑)
│   │   └── ProfileFragment.java     <-- Controller(我的页面逻辑)
│   │
│   ├── res/
│   │   ├── layout/
│   │   │   ├── activity_main.xml    <-- View(主界面布局)
│   │   │   ├── fragment_home.xml    <-- View(首页页面)
│   │   │   ├── fragment_rules.xml   <-- View(规则页面)
│   │   │   └── fragment_profile.xml <-- View(我的页面)
│   │   │
│   │   └── menu/
│   │       └── bottom_navigation_menu.xml <-- View(底部导航菜单定义)
│   │
│   └── drawable/
│       ├── ic_home.xml
│       ├── ic_rules.xml
│       └── ic_profile.xml           <-- View(图标资源)

代码 

MainActivity


import android.os.Bundle;
import android.util.Log;import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.navigation.NavigationBarView;public class MainActivity extends AppCompatActivity {private static final String TAG = "MainActivity";// 定义常量以替代资源 IDprivate static final int NAVIGATION_HOME = R.id.navigation_home;private static final int NAVIGATION_RULES = R.id.navigation_rules;private static final int NAVIGATION_PROFILE = R.id.navigation_profile;private FragmentManager fragmentManager;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);fragmentManager = getSupportFragmentManager();// 初始化底部导航栏BottomNavigationView bottomNavigationView = findViewById(R.id.bottom_navigation);bottomNavigationView.setOnItemSelectedListener(new NavigationBarView.OnItemSelectedListener() {@Overridepublic boolean onNavigationItemSelected(android.view.MenuItem item) {Log.d(TAG, "切换" + String.valueOf(item.getItemId()));Fragment selectedFragment = null;// 使用 if-else 替代 switch-case,避免变量重复赋值if (item.getItemId() == NAVIGATION_HOME) {selectedFragment = new HomeFragment();} else if (item.getItemId() == NAVIGATION_RULES) {selectedFragment = new RulesFragment();} else if (item.getItemId() == NAVIGATION_PROFILE) {selectedFragment = new ProfileFragment();}if (selectedFragment != null) {FragmentTransaction transaction = fragmentManager.beginTransaction();transaction.replace(R.id.fragment_container, selectedFragment);transaction.commit();}return true;}});// 默认显示首页bottomNavigationView.setSelectedItemId(NAVIGATION_HOME);}
}

HomeFragment

import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;public class HomeFragment extends Fragment {@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {return inflater.inflate(R.layout.fragment_home, container, false);}
}

ProfileFragment

import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;public class ProfileFragment extends Fragment {@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {return inflater.inflate(R.layout.fragment_profile, container, false);}
}

RulesFragment

import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;public class RulesFragment extends Fragment {@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {return inflater.inflate(R.layout.fragment_rules, container, false);}
}

bottom_navigation_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"><itemandroid:id="@+id/navigation_home"android:icon="@drawable/ic_home"android:title="首页" /><itemandroid:id="@+id/navigation_rules"android:icon="@drawable/ic_rules"android:title="规则" /><itemandroid:id="@+id/navigation_profile"android:icon="@drawable/ic_profile"android:title="我的" />
</menu>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"><FrameLayoutandroid:id="@+id/fragment_container"android:layout_width="match_parent"android:layout_height="0dp"app:layout_constraintTop_toTopOf="parent"app:layout_constraintBottom_toTopOf="@id/bottom_navigation" /><com.google.android.material.bottomnavigation.BottomNavigationViewandroid:id="@+id/bottom_navigation"android:layout_width="match_parent"android:layout_height="wrap_content"app:layout_constraintBottom_toBottomOf="parent"app:menu="@menu/bottom_navigation_menu" /></androidx.constraintlayout.widget.ConstraintLayout>

fragment_home.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:gravity="center"android:background="#FFFFFF"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="首页"android:textSize="24sp"android:textColor="#000000" /><!-- 新增一行文本,标识当前页面 --><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="这是首页页面"android:textSize="16sp"android:textColor="#000000"android:layout_marginTop="16dp" /></LinearLayout>

fragment_rules.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:gravity="center"android:background="#FFFFFF"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="规则"android:textSize="24sp"android:textColor="#000000" /><!-- 新增一行文本,标识当前页面 --><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="这是规则页面"android:textSize="16sp"android:textColor="#000000"android:layout_marginTop="16dp" /></LinearLayout>

fragment_profile.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:gravity="center"android:background="#FFFFFF"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="我的"android:textSize="24sp"android:textColor="#000000" /><!-- 新增一行文本,标识当前页面 --><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="这是我的页面"android:textSize="16sp"android:textColor="#000000"android:layout_marginTop="16dp" /></LinearLayout>

ic_home.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"android:width="24dp"android:height="24dp"android:viewportWidth="24"android:viewportHeight="24"><pathandroid:fillColor="#000000"android:pathData="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z" />
</vector>

ic_rules.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"android:width="24dp"android:height="24dp"android:viewportWidth="24"android:viewportHeight="24"><pathandroid:fillColor="#000000"android:pathData="M12 2L2 22h20L12 2z" />
</vector>

ic_profile.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"android:width="24dp"android:height="24dp"android:viewportWidth="24"android:viewportHeight="24"><pathandroid:fillColor="#000000"android:pathData="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm0 14.2c-2.5 0-4.71-0.98-6.29-2.58C4.59 15.72 4 13.55 4 11c0-1.66 0.59-3.22 1.57-4.42C5.16 6.21 6.42 5 8 5c1.58 0 3.04 1.21 3.92 2.59C11.96 6.78 13.22 5 14.8 5c1.58 0 3.04 1.21 3.92 2.59C19.41 7.78 20 9.34 20 11c0 2.55-0.59 4.72-1.57 6.22C17.71 19.02 15.5 20 12 20z" />
</vector>

效果

ending

人的一生 必须要学会做一件事 而且要做到透彻 才不枉此生...共勉 💪。

http://www.xdnf.cn/news/392941.html

相关文章:

  • 嵌入式学习笔记 - STM32 ADC,多重转换,内部参考电压,
  • linux基础操作4------(权限管理)
  • 产业带数据采集方案:1688 API 接口开发与实时数据解析实践
  • 【人工智能】 大模型训练的艺术:从数据到智能的飞跃
  • 【RP2350】香瓜树莓派RP2350之Delay延时
  • 基于SpringBoot的在线教育管理系统
  • spring
  • Python工具链UV整合环境管理
  • 国内外主流AI编程工具全方位对比分析(截至2025年5月)
  • SpringCloud Gateway知识点整理和全局过滤器实现
  • Python中,async和with结合使用,有什么好处?
  • redis数据结构-07(SADD、SREM、SMEMBERS)
  • c++STL-string的模拟实现
  • 谷歌与微软的AI战争:搜索、云服务与生态布局
  • 【Part 2安卓原生360°VR播放器开发实战】第四节|安卓VR播放器性能优化与设备适配
  • JVM调优-重启CPU飙高优化
  • SQlite数据库
  • 优化理赔数据同步机制:从4小时延迟降至15分钟
  • Day22 Kaggle泰坦尼克号训练实战
  • java加强 -List集合
  • LeetCode百题刷003(449周赛一二题)
  • 文件包含3
  • Qt 信号与槽及元对象系统
  • 判断两台设备是否在同一局域网内的具体方法
  • Unity 红点系统
  • Rockchip RK3308 开发(二)
  • 【人工智能】全面掌控:使用Python进行深度学习模型监控与调优
  • Springboot整合Swagger3
  • HttpServletResponse的理解
  • 【音视频工具】ffplay介绍