編輯:關於Android編程
1、概述
傳統的Android開發架構一般是MVC模式,
單獨從邏輯看起來非常好,與我們做Web開發時,開發模式類似,但在實際開發中,View對應於布局文件,實際上關於該布局文件中的數據綁定的操作,事件處理的代碼都在Activity中,Activity既像View又像Controller(MVVP架構中包括數據綁定),導致Activity中職責太重,耦合度大。修改和維護起來非常麻煩。
2、MVP介紹
MVP架構中,View 對應於Activity,負責View的繪制以及與用戶交互
Model 依然是業務邏輯和實體模型,Presenter 負責完成View於Model間的交互。
(1)Model層
模型層之中做的工作是具體業務邏輯處理的實現,都伴隨著程序中各種數據的處理,復雜一些的就需要實現一個Interface來松耦合了。
(2)View層
視圖層體現的很輕薄,負責顯示數據、提供友好界面跟用戶交互就行。MVP下Activity和Fragment體現在了這一 層,Activity一般也就做加載UI視圖、設置監聽再交由Presenter處理的一些工作,所以也就需要持有相應Presenter的引用。處理一些基本UI邏輯,判斷是否為空。
(3)Presenter層
Presenter這一層處理著程序各種邏輯的分發,收到View層UI上的反饋命令、定時命令、系統命令等指令後分發處理邏輯交由Model層做具體的業務操作。
MVP架構和MVC架構區別:
MVC中是允許Model和View進行交互的,而MVP中,Model與View之間的交互由Presenter完成。還有一點就是Presenter與View之間的交互是通過接口的。
3、MVP實現
百說不如一做。實現一個簡單的登錄操作。
項目結構如下:
(1)Model層實現
首先實現User實體類:
package com.chunsoft.blogcontent.bean; /** * Developer:chunsoft on 2017/2/7 11:19 * Content:實體類 */ public class User { private String username; private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
model層主要實現業務邏輯處理,在本文案例中,主要邏輯處理就是登錄,抽取了一個接口和一個實現類,在login操作,模擬登錄操作,Thread.sleep()模擬耗時,由於是耗時操作,通過一個回調接口通知登錄狀態。
model層接口:
package com.chunsoft.blogcontent.model; import com.chunsoft.blogcontent.RequestCallback; import com.chunsoft.blogcontent.bean.User; /** * Developer:chunsoft on 2017/2/7 11:30 * Email:[email protected] * Content:Model層主要處理業務方法和實體模型 */ public interface LoginModel { void login(String username, String password, RequestCallback<User> callback); }
model層接口實現:
package com.chunsoft.blogcontent.model.impl; import com.chunsoft.blogcontent.RequestCallback; import com.chunsoft.blogcontent.bean.User; import com.chunsoft.blogcontent.model.LoginModel; /** * Developer:chunsoft on 2017/2/7 11:31 * Content:Model層的實現 */ public class LoginModelImpl implements LoginModel{ @Override public void login(final String username, final String password, final RequestCallback<User> callback) { //模仿登錄操作 new Thread() { @Override public void run() { try { Thread.sleep(2*1000); } catch (InterruptedException e) { e.printStackTrace(); } if ("chunsoft".equals(username) && "123456".equals(password)) { User user = new User(); user.setUsername(username); user.setPassword(password); callback.onSuccess(user); } else { callback.onFailure("登錄失敗"); } } }.start(); } }
回調接口:
package com.chunsoft.blogcontent; /** * Developer:chunsoft on 2017/2/7 11:35 * Content:回調接口 */ public interface RequestCallback<T> { void onSuccess(T datas); void onFailure(String msg); }
(2)View層實現
對於View層接口定義,首先考慮功能上的操作,然後考慮:
view層接口:
package com.chunsoft.blogcontent.view; import com.chunsoft.blogcontent.bean.User; /** * Developer:chunsoft on 2017/2/7 11:54 * Email:[email protected] * Content:view層接口 */ public interface LoginView { String getUserName(); String getPassword(); void showLoading(); void hideLoading(); void toMainActvity(User user); void showFailedError(String msg); }
view層實現,其實就是Activity,可以看到Activity的代碼量大大減少,且邏輯清晰:
package com.chunsoft.blogcontent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ProgressBar; import android.widget.Toast; import com.chunsoft.blogcontent.bean.User; import com.chunsoft.blogcontent.presenter.impl.LoginPresenterImpl; import com.chunsoft.blogcontent.view.LoginView; public class MainActivity extends AppCompatActivity implements LoginView{ private EditText et_mobile,et_password; private ProgressBar pb; private Button btn_login; private LoginPresenterImpl mLoginPresenter = new LoginPresenterImpl(this); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); et_mobile = (EditText) findViewById(R.id.et_mobile); et_password = (EditText) findViewById(R.id.et_password); pb = (ProgressBar) findViewById(R.id.pb); btn_login = (Button) findViewById(R.id.btn_login); btn_login.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mLoginPresenter.login(); } }); } @Override public String getUserName() { return et_mobile.getText().toString(); } @Override public String getPassword() { return et_password.getText().toString(); } @Override public void showLoading() { pb.setVisibility(View.VISIBLE); } @Override public void hideLoading() { pb.setVisibility(View.INVISIBLE); } @Override public void toMainActvity(User user) { Toast.makeText(this,user.getUsername() + "登錄成功",Toast.LENGTH_SHORT).show(); } @Override public void showFailedError(String msg) { Toast.makeText(this,msg,Toast.LENGTH_SHORT).show(); } }
(3)Presenter層實現
Presenter層是Model層和View層的橋梁,本文中依然抽象出一個接口和一個實現類,定義時主要看該功能有什麼操作,例如,登錄:
Presenter接口:
package com.chunsoft.blogcontent.presenter; /** * Developer:chunsoft on 2017/2/7 11:49 * Content:Presenter層接口 */ public interface LoginPresenter { void login(); }
Presenter層實現:
package com.chunsoft.blogcontent.presenter.impl; import android.os.Handler; import com.chunsoft.blogcontent.RequestCallback; import com.chunsoft.blogcontent.bean.User; import com.chunsoft.blogcontent.model.LoginModel; import com.chunsoft.blogcontent.model.impl.LoginModelImpl; import com.chunsoft.blogcontent.presenter.LoginPresenter; import com.chunsoft.blogcontent.view.LoginView; /** * Developer:chunsoft on 2017/2/7 11:50 * Content:Presenter層實現 */ public class LoginPresenterImpl implements LoginPresenter { private LoginView loginView; private LoginModel loginModel; private Handler mHandler = new Handler(); //在構造函數中初始化 public LoginPresenterImpl(LoginView loginView) { this.loginModel = new LoginModelImpl(); this.loginView = loginView; } @Override public void login() { loginView.showLoading(); loginModel.login(loginView.getUserName(), loginView.getPassword(), new RequestCallback<User>() { @Override public void onSuccess(final User datas) { //登錄成功 mHandler.post(new Runnable() { @Override public void run() { loginView.toMainActvity(datas); loginView.hideLoading(); } }); } @Override public void onFailure(final String msg) { //登錄失敗 mHandler.post(new Runnable() { @Override public void run() { loginView.showFailedError(msg); loginView.hideLoading(); } }); } }); } }
Presenter層是Model層和View層的橋梁,Model層和View層不直接通信,所以Presenter層需要Model層和View層的實現類,從View層中獲取重要參數,交給Model 層調用業務邏輯處理,執行後的結果和反饋再交給View層去展示。
本文源碼下載
本文是簡單的用MVP架構實現登錄操作,而目前主流開發,將Rxjava、Retrofit和MVP結合進行開發,邏輯更加清晰,下篇文章將詳細介紹這部分實現。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持本站。
(本Demo的開發環境為Android Studio)1.先去百度翻譯開放平台(http://api.fanyi.baidu.com/api/trans/product/
Android UI之RealtiveLayout(相對布局)說明:RealtiveLayout是目前android開發中最最常用的布局管理器(比LinearLayout
android大家都有很多需要用戶上傳頭像的需求,有的是選方形,有的是圓角矩形,有的是圓形。首先我們要做一個處理圖片的自定義控件,把傳入的圖片,經過用戶選擇區域,處理成一
自定義的textView,滿足一些的特殊的需求。效果如下:1.自定義的類/** * */ package com.zhang.test; import android.c