Android的一種MVP模式架構

來源:互聯網
上載者:User

標籤:

今天給大家分享的是一種將view的初始化和邏輯與activity分離的架構,採用的是mvp模式。但令人遺憾的是,這僅僅是一個新的思路,我在實際使用中發現其並不能完全將UI邏輯與activity分開,所以在實際中沒辦法認為這種設計是合理的。設計的初衷是覺得activity要接收intent或者要進行很多其他的處理,很難讓人認為activity是一個與View相關的類,所以我們的想法是將view的邏輯從activity中分離,這種分離的方式我們就要用到一個UI類的介面。這個思路來自:https://github.com/wongcain/MVP-Simple-Demo,我僅僅是對作者的代碼進行了分析和小部分修改。

 

ViewUiImp.java

package frame.kale.com.frame;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;/** * @author Jack Tony * @brief * @date 2015/4/4 */public interface ViewUiImp {    /**     *     * @param inflater          * @param container     */    public void initViews(LayoutInflater inflater, ViewGroup container);    public View getRootView();}

這個介面中只有兩個方法,一個是初始化views的方法,一個是得到根view的方法。我們希望activity僅僅與這個介面進行互動,而不用管view的邏輯。view的邏輯判斷都是在實現這個介面的類中來進行的。為了讓activity能更好的複用 代碼,這裡我們需要建立一個 activity的基類。

 

BasePresenterActivity.java

package frame.kale.com.frame;import android.app.Activity;import android.os.Bundle;/** * @author Jack Tony * @brief 與activity有關的表現層的基類 * @date 2015/4/4 */public  abstract class BasePresenterActivity <V extends ViewUiImp> extends Activity {    protected V uiImp; // ViewUiImp的對象    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        try {            // 產生一個對象,並且調用initViews方法來初始化views            uiImp = getViewUiClass().newInstance();            uiImp.initViews(getLayoutInflater(), null);            // 把根view設定到activity中            setContentView(uiImp.getRootView());            // 綁定views            onBindViewUi();        } catch (InstantiationException e) {            e.printStackTrace();        } catch (IllegalAccessException e) {            e.printStackTrace();        }    }            /**     * 當activity退出後,通過onDestroyViewUi來銷毀views     */       @Override    protected final void onDestroy() {        onDestroyViewUi();        uiImp = null;        super.onDestroy();    }    protected abstract Class<V> getViewUiClass();    /**     * 綁定views時觸發的方法     */    protected void onBindViewUi(){}    /**     * 移出views時觸發的方法     */    protected void onDestroyViewUi() {}}

可以看到我們通過newInstance()來初始化了一個ViewUiImp對象,並且通過getRootView()來得到根view,之後將這個根view設定進了activity中。這些步驟中我們看到的都是介面對象,沒有任何實體,靈活性很強。此外,在activity初始化或者銷毀時都會觸發view被綁定或被銷毀時的回調,便於我們在activity的子類中進行操作。

 

現在,我們搭好了架構,那麼就來嘗試寫一個實作類別來看看效果如何吧。

package frame.kale.com.frame;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.EditText;import android.widget.TextView;/** * @author Jack Tony * @brief * @date 2015/4/4 */public class HelloWorldViewUi implements ViewUiImp{    private View rootView;        public TextView helloWorldTv;    public EditText msgEt;        @Override    public void initViews(LayoutInflater inflater, ViewGroup container) {        rootView = inflater.inflate(R.layout.activity_main, container, false);        helloWorldTv = (TextView) rootView.findViewById(R.id.textView);        msgEt = (EditText) rootView.findViewById(R.id.editText);    }    @Override    public View getRootView() {        return rootView;    }}

這個類很簡單,做了初始化views和返回根view的操作。目前看來findviewById的方法和view的邏輯都可以在這裡進行。那麼我們在activity的實作類別中會做什麼事情呢?我們做的事情也很簡單,只需要繼承我們剛寫的基類,並且注入一個HelloWorldViewUi對象就可以了。

public class MainActivity extends BasePresenterActivity<HelloWorldViewUi> {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        uiImp.helloWorldTv.setText("12345");    }    @Override    protected Class<HelloWorldViewUi> getViewUiClass() {        return HelloWorldViewUi.class;    }}

我們可以利用這個uiImp對象來操作布局中定義的各種view,確實很簡潔方便。但問題又來了!這裡看到的確實是將ui和activity進行了抽離,但activity仍舊會進行ui邏輯的操作,對於menu這樣的初始化和定義還是在activity中進行的,所以目前來看view和activity沒有完全的獨立開。比如下面的代碼就很難放入uiImp介面中去。

@Override    public boolean onCreateOptionsMenu(Menu menu) {        // Inflate the menu; this adds items to the action bar if it is present.        getMenuInflater().inflate(R.menu.menu_main, menu);        return true;    }    @Override    public boolean onOptionsItemSelected(MenuItem item) {        // Handle action bar item clicks here. The action bar will        // automatically handle clicks on the Home/Up button, so long        // as you specify a parent activity in AndroidManifest.xml.        int id = item.getItemId();        //noinspection SimplifiableIfStatement        if (id == R.id.action_settings) {            return true;        }        return super.onOptionsItemSelected(item);    }

總結一下就是這個思路很不錯,但在實際使用中還是有一定問題的,以後還得多思考多研究啊。

 

源碼下載:http://download.csdn.net/detail/shark0017/8565091

 

參考自:

https://github.com/wongcain/MVP-Simple-Demo

https://github.com/bboyfeiyu/android-tech-frontier/tree/master/androidweekly/%E4%B8%80%E7%A7%8D%E5%9C%A8android%E4%B8%AD%E5%AE%9E%E7%8E%B0MVP%E6%A8%A1%E5%BC%8F%E7%9A%84%E6%96%B0%E6%80%9D%E8%B7%AF

 

Android的一種MVP模式架構

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.