Android——MVC、MVP、MVVM框架实现登录示例

简介: MVC描述缺点优点MVP效果图描述缺点优点代码解析视图效果图建立实体类建立实体类接口实现实体类接口设置P层建立交互接口数据绑定MVVM效果图描述代码解析导入dataBinding实体类建立viewmodelxml绑定数据视图与数据绑定


MVC



描述

自如其意,MVC分为三部分:M层、V层、C层。

M层:model层,主要用于逻辑处理。

V层:view层,主要指Activity、Dialog、Fragment,用于视图展示。

C层:controller层,用于视图层与数据层交互,此处由Activity充当。


缺点

视图层与数据层没有完成解耦,随着逻辑增多,会使Activity非常拥堵。


优点

比一个文件闯天下,稍微好一点


MVP



效果图

image.png

描述

自如其意,MVP分为三部分:M层、V层、P层。

M层:model层,主要用于逻辑处理。

V层:view层,主要指Activity、Dialog、Fragment,用于视图展示。

P层:presenter层,用于视图层与数据层交互。通过接口实现交互。


缺点

随着逻辑增多,用于实现视图层与数据层交互的接口数据就会增多

优点

数据层与视图层完成解耦


代码解析

视图效果图

image.png

建立实体类

public class User{
    private String UserName;
    private String PassWord;
    public User(String UserName,String PassWord){
        this.PassWord = PassWord;
        this.UserName = UserName;
    }
    public User(){
    }
    public String getUserName() {
        return UserName;
    }
    public void setUserName(String userName) {
        UserName = userName;
    }
    public String getPassWord() {
        return PassWord;
    }
    public void setPassWord(String passWord) {
        PassWord = passWord;
    }
}

建立实体类接口

public interface IUser {
    boolean LoginAccount(String userName,String passWord);
}

实现实体类接口

public class exeLogin implements IUser {
    private User user;
    @Override
    public boolean LoginAccount(String userName,String passWord) {
        if (userName.equals( "admin" ) && passWord.equals( "123456" )){
            user = new User(  );
            user.setUserName( userName );
            user.setPassWord( passWord );
            return true;
        }
        return false;
    }
}

设置P层

public class LoginPresenter {
    private exeLogin exeLogin;
    private IMain iMain;
    public LoginPresenter(IMain iMain){
        this.iMain = iMain;
        exeLogin = new exeLogin();
    }
    public void Login(){
        String userName = iMain.getUserName();
        String passWord = iMain.getPassWord();
        boolean isSuccess = exeLogin.LoginAccount( userName,passWord  );
        iMain.Login( isSuccess );
    }
}

建立交互接口

public interface IMain {
    String getUserName();
    String getPassWord();
    void Login(Boolean isLoginSuccess);
}

数据绑定

public class MainActivity extends AppCompatActivity implements IMain{
    private EditText userName,passWord;
    private Button btnLogin;
    private Context context = null;
    private LoginPresenter loginPresenter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate( savedInstanceState );
        setContentView( R.layout.activity_main );
        InitView();
        Listener();
    }
    private void InitView(){
        userName = findViewById( R.id.username );
        passWord = findViewById( R.id.password );
        btnLogin = findViewById( R.id.login );
        loginPresenter = new LoginPresenter( this );
        if (context == null){
            context = MainActivity.this;
        }
    }
    private void Listener(){
        btnLogin.setOnClickListener( new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                loginPresenter.Login();
                Log.d( "TAG","click success" );
            }
        } );
    }
    @Override
    public String getUserName() {
        return userName.getText().toString().trim();
    }
    @Override
    public String getPassWord() {
        return passWord.getText().toString().trim();
    }
    @Override
    public void Login(Boolean isLoginSuccess) {
        if (isLoginSuccess){
            Toast.makeText( MainActivity.this,"Success",Toast.LENGTH_SHORT ).show();
            Log.d( "TAG","Success" );
        }else {
            Toast.makeText( MainActivity.this,"Fail",Toast.LENGTH_SHORT ).show();
            Log.d( "TAG","Fail" );
        }
    }
}

MVVM



效果图

image.png


描述

Model层:

数据处理

View层

实体

ViewModel:

实现视图与数据的交互,将二者分离,实现解耦


代码解析

导入dataBinding

image.png
dataBinding {
            enabled = true
        }

实体类

public class User extends BaseObservable {
    public String mUserName;
    public String mPassWord;
    public User(){
    }
    public User(String mUserName,String mPassWord){
        this.mUserName = mUserName;
        this.mPassWord = mPassWord;
    }
    @Bindable
    public String getmUserName() {
        return mUserName;
    }
    /**
     * @param mUserName */
    public void setmUserName(String mUserName) {
        this.mUserName = mUserName;
        notifyPropertyChanged( BR.mUserName );
    }
    @Bindable
    public String getmPassWord() {
        return mPassWord;
    }
    /**
     * @param mPassWord */
    public void setmPassWord(String mPassWord) {
        this.mPassWord = mPassWord;
        notifyPropertyChanged( BR.mPassWord );
    }
}

添加 @Bindable,作为xml绑定字段

 @Bindable
    public String getmUserName() {
        return mUserName;
    }

BR是一个自动生成的类,大致内容为将每一个字段添加ID,通过notifyPropertyChanged实现数据更新

/**
     * @param mUserName */
    public void setmUserName(String mUserName) {
        this.mUserName = mUserName;
        notifyPropertyChanged( BR.mUserName );
    }


建立viewmodel

public class ViewModel {
    private ActivityMainBinding binding;
    public User user;
    public ViewModel(ActivityMainBinding binding,User user){
        this.binding = binding;
        this.user = user;
    }
    public void Login(View view){
        if (user.getmUserName().equals( "admin" ) && user.getmPassWord().equals( "123456" )){
            Log.d( "TAG","success" );
        }else {
            Log.d( "TAG","fail" );
        }
        Log.d( "TAG",user.getmUserName()+"" );
        Log.d( "TAG",user.getmPassWord()+"" );
    }
}


xml绑定数据

注意视图绑定数据层字段时,一个等于=符号产生不同结果,如果没有等于,我在输入框输入的数据,实体类数据不会刷新,加上等号,完成数据双向绑定。

密码输入框中输入123456

android:text="@={viewmodel.user.mPassWord}"

image.png

密码输入框中输入123456,而打印出来是12345,并没有完成双向绑定

android:text="@{viewmodel.user.mPassWord}"

image.png

<?xml version="1.0" encoding="utf-8"?>
<layout
    xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable
        name="user"
        type="com.franzliszt.mvvmtest.model.User" />
        <variable
            name="viewmodel"
            type="com.franzliszt.mvvmtest.viewmodel.ViewModel" />
    </data>
    <LinearLayout
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        >
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingTop="40dp">
        </LinearLayout>
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingLeft="30dp"
            android:text="账号密码登录"
            android:textColor="#000000"
            android:textSize="30sp"
            android:layout_marginTop="20dp"/>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:layout_margin="20dp">
            <EditText
                android:id="@+id/username"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="用户名"
                android:paddingLeft="10dp"
                android:singleLine="true"
                android:textColor="#ff000000"
                android:textSize="15sp"
                android:text="@={viewmodel.user.mUserName}"
                />
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="20dp">
            <EditText
                android:id="@+id/password"
                android:layout_width="match_parent"
                android:layout_height="40dp"
                android:layout_marginTop="10dp"
                android:hint="密   码"
                android:paddingLeft="10dp"
                android:password="true"
                android:textColor="#ff000000"
                android:textSize="15sp"
                android:text="@={viewmodel.user.mPassWord}"
                />
        </LinearLayout>
        <Button
            android:id="@+id/login"
            android:layout_width="200dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="80dp"
            android:layout_marginTop="10dp"
            android:background="#1A73E8"
            android:text="登录"
            android:textColor="#ffffff"
            android:textSize="15sp"
            android:onClick="@{viewmodel.Login}"/>
    </LinearLayout>
</layout>


视图与数据绑定

初始化User类的数据, 完成视图与数据绑定

public class MainActivity extends AppCompatActivity {
    private ActivityMainBinding binding;
    private User user;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate( savedInstanceState );
        binding = DataBindingUtil.setContentView( this,R.layout.activity_main );
        user = new User( "admin","12345" );
        binding.setViewmodel( new ViewModel( binding,user ) );
    }
}

相关文章
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台框架解析
在移动应用开发的广阔舞台上,安卓和iOS一直是两大主角。随着技术的进步,开发者们渴望能有一种方式,让他们的应用能同时在这两大平台上运行,而不必为每一个平台单独编写代码。这就是跨平台框架诞生的背景。本文将探讨几种流行的跨平台框架,包括它们的优势、局限性,以及如何根据项目需求选择合适的框架。我们将从技术的深度和广度两个维度,对这些框架进行比较分析,旨在为开发者提供一个清晰的指南,帮助他们在安卓和iOS的开发旅程中,做出明智的选择。
|
前端开发 Java 编译器
当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
694 36
当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
|
物联网 区块链 vr&ar
未来已来:探索区块链、物联网与虚拟现实技术的融合与应用安卓与iOS开发中的跨平台框架选择
【8月更文挑战第30天】在科技的巨轮下,新技术不断涌现,引领着社会进步。本文将聚焦于当前最前沿的技术——区块链、物联网和虚拟现实,探讨它们各自的发展趋势及其在未来可能的应用场景。我们将从这些技术的基本定义出发,逐步深入到它们的相互作用和集成应用,最后展望它们如何共同塑造一个全新的数字生态系统。
|
算法 JavaScript Android开发
|
前端开发
MVVM是什么?和MVC有何区别呢?
【10月更文挑战第11天】MVVM 和 MVC 都是为了更好地组织和管理软件架构,提高开发效率和代码质量。理解它们的特点和区别,有助于我们在实际开发中做出更合适的选择,并构建出更加优秀的应用程序。
|
编译器 Android开发 开发者
带你了解Android Jetpack库中的依赖注入框架:Hilt
本文介绍了Hilt,这是Google为Android开发的依赖注入框架,基于Dagger构建,旨在简化依赖注入过程。Hilt通过自动化的组件和注解减少了DI的样板代码,提高了应用的可测试性和可维护性。文章详细讲解了Hilt的主要概念、基本用法及原理,帮助开发者更好地理解和应用Hilt。
1169 18
|
存储 前端开发 测试技术
MVC、MVP、MVVM 模式
MVC、MVP 和 MVVM 是三种常见的软件架构模式,用于分离用户界面和业务逻辑。MVC(Model-View-Controller)通过模型、视图和控制器分离数据、界面和控制逻辑;MVP(Model-View-Presenter)将控制逻辑移到 Presenter 中,减少视图的负担;MVVM(Model-View-ViewModel)通过数据绑定机制进一步解耦视图和模型,提高代码的可维护性和测试性。
|
Java 程序员 API
Android|集成 slf4j + logback 作为日志框架
做个简单改造,统一 Android APP 和 Java 后端项目打印日志的体验。
1150 1
|
前端开发 Java 数据库
💡Android开发者必看!掌握这5大框架,轻松打造爆款应用不是梦!🏆
在Android开发领域,框架犹如指路明灯,助力开发者加速应用开发并提升品质。本文将介绍五大必备框架:Retrofit简化网络请求,Room优化数据库访问,MVVM架构提高代码可维护性,Dagger 2管理依赖注入,Jetpack Compose革新UI开发。掌握这些框架,助你在竞争激烈的市场中脱颖而出,打造爆款应用。
1730 3
|
设计模式 Java Android开发
探索安卓应用开发:从新手到专家的旅程探索iOS开发中的SwiftUI框架
【8月更文挑战第29天】本文旨在通过一个易于理解的旅程比喻,带领读者深入探讨安卓应用开发的各个方面。我们将从基础概念入手,逐步过渡到高级技术,最后讨论如何维护和推广你的应用。无论你是编程新手还是有经验的开发者,这篇文章都将为你提供有价值的见解和实用的代码示例。让我们一起开始这段激动人心的旅程吧!

热门文章

最新文章