MVC、MVP、MVVM框架實作登錄示例
- MVC
- 描述
- 缺點
- 優點
- MVP
- 效果圖
- 描述
- 缺點
- 優點
- 代碼決議
- 視圖效果圖
- 建立物體類
- 建立物體類介面
- 實作物體類介面
- 設定P層
- 建立互動介面
- 資料系結
- MVVM
- 效果圖
- 描述
- 代碼決議
- 匯入dataBinding
- 物體類
- 建立viewmodel
- xml系結資料
- 視圖與資料系結
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 ) );
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/336276.html
標籤:其他
上一篇:天塌了,近百套開源框架原始碼全新分享,熬夜看完,靈魂都隨之升華。
下一篇:【Android原始碼決議】一篇搞定“路由、網路層、UI層、通信層....百大框架”原始碼決議,阿里大牛神級之作
