溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Android MVP模式實(shí)戰(zhàn)教程

發(fā)布時(shí)間:2020-10-11 19:48:11 來源:腳本之家 閱讀:121 作者:lfendo 欄目:移動開發(fā)

一、什么是MVP

在網(wǎng)上找了些資料,整理如下:

  MVP是模型(Model)、視圖(View)、主持人(Presenter)的縮寫,分別代表項(xiàng)目中3個(gè)不同的模塊。

  模型(Model):負(fù)責(zé)處理數(shù)據(jù)的加載或者存儲,比如從網(wǎng)絡(luò)或本地?cái)?shù)據(jù)庫獲取數(shù)據(jù)等;
  視圖(View):負(fù)責(zé)界面數(shù)據(jù)的展示,與用戶進(jìn)行交互;
  主持人(Presenter):相當(dāng)于協(xié)調(diào)者,是模型與視圖之間的橋梁,將模型與視圖分離開來。

如下圖所示,View與Model并不直接交互,而是使用Presenter作為View與Model之間的橋梁。其中Presenter中同時(shí)持有Viwe層以及Model層的Interface的引用,而View層持有Presenter層Interface的引用。當(dāng)View層某個(gè)界面需要展示某些數(shù)據(jù)的時(shí)候,首先會調(diào)用Presenter層的某個(gè)接口,然后Presenter層會調(diào)用Model層請求數(shù)據(jù),當(dāng)Model層數(shù)據(jù)加載成功之后會調(diào)用Presenter層的回調(diào)方法通知Presenter層數(shù)據(jù)加載完畢,最后Presenter層再調(diào)用View層的接口將加載后的數(shù)據(jù)展示給用戶。這就是MVP模式的整個(gè)核心過程。

Android MVP模式實(shí)戰(zhàn)教程

在MVP模式里通常包含4個(gè)要素:

     (1)View:負(fù)責(zé)繪制UI元素、與用戶進(jìn)行交互(在Android中體現(xiàn)為Activity);
     (2)View interface:需要View實(shí)現(xiàn)的接口,View通過View interface與Presenter進(jìn)行交互,降低耦合,方便進(jìn)行單元測試;
     (3)Model:負(fù)責(zé)存儲、檢索、操縱數(shù)據(jù)(有時(shí)也實(shí)現(xiàn)一個(gè)Model interface用來降低耦合);
     (4)Presenter:作為View與Model交互的中間紐帶,處理與用戶交互的負(fù)責(zé)邏輯。

Android MVP模式實(shí)戰(zhàn)教程

二、MVP模式的使用

Android MVP模式實(shí)戰(zhàn)教程

上面一張簡單的MVP模式的UML圖,從圖中可以看出,使用MVP,至少需要經(jīng)歷以下步驟:

1.創(chuàng)建IPresenter接口,把所有業(yè)務(wù)邏輯的接口都放在這里,并創(chuàng)建它的實(shí)現(xiàn)PresenterCompl(在這里可以方便地查看業(yè)務(wù)功能,由于接口可以有多種實(shí)現(xiàn)所以也方便寫單元測試)

2.創(chuàng)建IView接口,把所有視圖邏輯的接口都放在這里,其實(shí)現(xiàn)類是當(dāng)前的Activity/Fragment

3.由UML圖可以看出,Activity里包含了一個(gè)IPresenter,而PresenterCompl里又包含了一個(gè)IView并且依賴了Model。Activity里只保留對IPresenter的調(diào)用,其它工作全部留到PresenterCompl中實(shí)現(xiàn)

4.Model并不是必須有的,但是一定會有View和Presenter

三、一個(gè)簡單的MVP示例

實(shí)現(xiàn)一個(gè)簡單的用戶登錄

效果如下:

Android MVP模式實(shí)戰(zhàn)教程

先來看看java文件的目錄結(jié)構(gòu):

Android MVP模式實(shí)戰(zhàn)教程

1.Baen包

UserBean

package com.example.mvpe.bean; 
 
/** 
 * Created by fendo on 2017/4/29. 
 */ 
 
public class UserBean { 
 private String username; 
 private String userpwd; 
 
 public UserBean() { 
 } 
 
 public UserBean(String username, String userpwd) { 
 this.username = username; 
 this.userpwd = userpwd; 
 } 
 
 public String getUsername() { 
 return username; 
 } 
 
 public void setUsername(String username) { 
 this.username = username; 
 } 
 
 public String getUserpwd() { 
 return userpwd; 
 } 
 
 public void setUserpwd(String userpwd) { 
 this.userpwd = userpwd; 
 } 
} 

2.Model包

IUserModel類

package com.example.mvpe.model; 
 
import com.example.mvpe.bean.UserBean; 
 
/** 
 * Created by fendo on 2017/4/29. 
 */ 
 
public interface IUserModel { 
 
 void setSid(int cid); 
 UserBean load(int sid); 
 void setUsername(String username); 
 void setUserpwd(String userpwd); 
} 

UserModelimp類

package com.example.mvpe.model; 
 
import android.provider.Settings; 
import android.util.Log; 
import android.util.SparseArray; 
 
import com.example.mvpe.bean.UserBean; 
 
/** 
 * Created by fendo on 2017/4/29. 
 */ 
 
public class UserModelimp implements IUserModel{ 
 
 private static final String ACTIVITY_TAG="UserModelimp"; 
 private String username; 
 private String userpwd; 
 private int sid; 
 private SparseArray<UserBean> su=new SparseArray<UserBean>(); 
 
 @Override 
 public void setSid(int cid) { 
 sid=cid; 
 } 
 
 @Override 
 public UserBean load(int sidy) { 
 sid=sidy; 
 UserBean ub=su.get(sid,new UserBean("not found", 
  "not found")); 
 return ub; 
 } 
 
 
 @Override 
 public void setUsername(String usernamey) { 
 username=usernamey; 
 } 
 
 @Override 
 public void setUserpwd(String userpwdy) { 
 userpwd=userpwdy; 
 UserBean usb=new UserBean(username,userpwd); 
 System.out.print(username+"----"+userpwd+"----"+sid); 
 Log.d(UserModelimp.ACTIVITY_TAG, "Start_OK"+username+"----"+userpwd+"----"+sid); 
 su.append(sid,usb); 
 } 
} 

3.persenter包

UserPersenter類

package com.example.mvpe.presenter; 
 
import android.util.Log; 
import android.view.View; 
 
import com.example.mvpe.bean.UserBean; 
import com.example.mvpe.model.IUserModel; 
import com.example.mvpe.model.UserModelimp; 
import com.example.mvpe.view.IUserView; 
 
 
 
/** 
 * Created by fendo on 2017/4/29. 
 */ 
 
public class UserPersenter { 
 
 private static final String ACTIVITY_TAG="UserPersenter"; 
 
 private IUserView iUserView; 
 private IUserModel iUserModel; 
 
 public UserPersenter(IUserView view){ 
 iUserView=view; 
 iUserModel=new UserModelimp(); 
 } 
 
 public void saveuser(int sid,String username,String userpwd){ 
 iUserModel.setSid(sid); 
 iUserModel.setUsername(username); 
 iUserModel.setUserpwd(userpwd); 
 } 
 
 public void loaduser(int sid){ 
 UserBean usb=iUserModel.load(sid); 
 Log.d(ACTIVITY_TAG, "loaduser: "+usb.getUsername()); 
 iUserView.setUsername(usb.getUsername()); 
 iUserView.setUserpwd(usb.getUserpwd()); 
 } 
 
} 

4.view包

IUserView類

package com.example.mvpe.view; 
 
import com.example.mvpe.bean.UserBean; 
 
/** 
 * Created by fendo on 2017/4/29. 
 */ 
 
public interface IUserView { 
 
 int getID(); 
 
 void setUsername(String username); 
 void setUserpwd(String userpwd); 
 
 String getUserpwd(); 
 String getUsername(); 
} 

UserActivity類

package com.example.mvpe.view; 
 
import android.app.Activity; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.Button; 
import android.widget.EditText; 
 
import com.example.mvpe.R; 
import com.example.mvpe.presenter.UserPersenter; 
import android.view.View.OnClickListener; 
import android.widget.Toast; 
 
/** 
 * Created by fendo on 2017/4/29. 
 */ 
 
public class UserActivity extends Activity implements OnClickListener,IUserView{ 
 
 private EditText userid; 
 private EditText username; 
 private EditText userpwd; 
 private Button read; 
 private Button write; 
 private UserPersenter usp; 
 
 @Override 
 protected void onCreate(Bundle savedInstanceState) { 
 super.onCreate(savedInstanceState); 
 usp=new UserPersenter(this); 
 setContentView(R.layout.activity_main); 
 findviewbyid(); 
 read.setOnClickListener(this); 
 write.setOnClickListener(this); 
 } 
 
 
 public void findviewbyid(){ 
 userid= (EditText) findViewById(R.id.userid); 
 username= (EditText) findViewById(R.id.usertext); 
 userpwd= (EditText) findViewById(R.id.userpwd); 
 read= (Button) findViewById(R.id.read); 
 write= (Button) findViewById(R.id.write); 
 } 
 
 @Override 
 public int getID() { 
 return Integer.parseInt(userid.getText().toString()); 
 } 
 
 @Override 
 public void setUsername(String usernamcc) { 
 username.setText(usernamcc); 
 } 
 
 @Override 
 public void setUserpwd(String userpw) { 
 userpwd.setText(userpw); 
 } 
 
 @Override 
 public String getUserpwd() { 
 return userpwd.getText().toString(); 
 } 
 
 @Override 
 public String getUsername() { 
 return username.getText().toString(); 
 } 
 
 
 @Override 
 public void onClick(View view) { 
 switch (view.getId()) { 
  case R.id.read : 
  usp.loaduser(getID()); 
  Toast.makeText(getApplicationContext(), "點(diǎn)擊了讀"+getID(), Toast.LENGTH_SHORT).show(); 
 
  break; 
  case R.id.write: 
  usp.saveuser(getID(),getUsername(),getUserpwd()); 
  Toast.makeText(getApplicationContext(), "點(diǎn)擊了存"+getID()+"--"+getUsername()+"--"+getUserpwd(), Toast.LENGTH_SHORT).show(); 
  break; 
 } 
 } 
} 

可以看到View只負(fù)責(zé)處理與用戶進(jìn)行交互,并把數(shù)據(jù)相關(guān)的邏輯操作都扔給了Presenter去做。而Presenter調(diào)用Model處理完數(shù)據(jù)之后,再通過IUserView更新View顯示的信息。

下載:源碼

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI