MVC
描述
自如其意,MVC分为三部分:M层、V层、C层。
M层:model层,主要用于逻辑处理。
V层:view层,主要指Activity、Dialog、Fragment,用于视图展示。
C层:controller层,用于视图层与数据层交互,此处由Activity充当。
缺点
视图层与数据层没有完成解耦,随着逻辑增多,会使Activity非常拥堵。
优点
比一个文件闯天下,稍微好一点
MVP
效果图
描述
自如其意,MVP分为三部分:M层、V层、P层。
M层:model层,主要用于逻辑处理。
V层:view层,主要指Activity、Dialog、Fragment,用于视图展示。
P层:presenter层,用于视图层与数据层交互。通过接口实现交互。
缺点
随着逻辑增多,用于实现视图层与数据层交互的接口数据就会增多
优点
数据层与视图层完成解耦
代码解析
视图效果图
建立实体类
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
效果图
描述
Model层:
数据处理
View层
实体
ViewModel:
实现视图与数据的交互,将二者分离,实现解耦
代码解析
导入dataBinding
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}"
密码输入框中输入123456,而打印出来是12345,并没有完成双向绑定
android:text="@{viewmodel.user.mPassWord}"
<?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 ) ); } }