1. 程式人生 > >Android MVC 模式的介紹 與 實戰

Android MVC 模式的介紹 與 實戰

文章目錄

1、mvc 框架圖

在這裡插入圖片描述

經典的mvc 模式如圖所示
1)Model (模型層) 在 MVC 中 Model 一般用來儲存資料的狀態,比如資料儲存,網路請求。同時還與View 存在一定的耦合,通過某種事件機制(比如觀察者模式) 通知 View 狀態的改變來讓view 更新。

2)View (檢視層)一般由一些GUI 組建組成,同時響應使用者的互動行為並觸發 Controller 的邏輯,View 還有可能修改Model 的狀態 以使其與 Model 同步,View 還會在model 中註冊 model 事件的改變。以此來重新整理自己並展示給使用者。

3)Control (控制層)控制器由View 根據使用者行為觸發並響應來自view 的使用者互動,然後根據view 的事件邏輯來修改對應的Model, Control 並不關心 View 如何展示 相關資料或狀態,而是通過修改 Model 來實現view 的資料的重新整理。

2、MVC 在Android 模式裡的實現

在Android 中 MVC 模式運用的特別多,大的方面。我們可以把一個xml 看作一個 View, Activity 看作一個 Control , Model 則是由相關的資料操作類來承擔。
我們以一個圖爿的載入和清除為例:

  1. 程式碼架構:
    在這裡插入圖片描述

  2. Model 類,用於資料的運算 儲存

package com.example.menglux.mvcproject;


import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;

/**
 * Created by menglux on 15/10/2018.
 */

public class Model {
    private final Handler mHandler = new Handler() ;
    private OnStateChangeListener mListener;  //Model 狀態改變監聽器

    private Bitmap mBitmap;   //展示的圖片
    private Context mContext;


    public interface  OnStateChangeListener {  //設定監聽Model 狀態改變的介面
        void OnStateChanged(Bitmap image);   //設定圖片
    }

    public Model (Context context) {
        mContext = context;
        //初始化時 預載入一個圖片 作為預設圖爿

        mBitmap = BitmapFactory.decodeResource(context.getResources(),R.mipmap.ic_launcher);
    }

    //設定監聽物件
    public void setOnStateChangeListener(OnStateChangeListener listener) {
        mListener = listener;
    }

    public void loadImage() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    //模擬耗時操作
                    Thread.sleep(3000);

                    //獲取影象
                    mBitmap = BitmapFactory.decodeResource(mContext.getResources(),R.mipmap.agns);

                    //回傳給 View
                    if (null != mListener) {
                        mHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                mListener.OnStateChanged(mBitmap); //將監聽的物件狀態改變
                            }
                        });
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }


    public void clear () {
        //清楚影象
        mBitmap = null;

        //回傳給View
        if (null != mListener) {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    mListener.OnStateChanged(mBitmap); //將監聽的物件狀態改變
                }
            });
        }
    }

    public  Bitmap getImage() {
        return  mBitmap;
    }
}




3) 充當 view 的 xml 佈局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    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"
    tools:context="com.example.menglux.mvcproject.MainActivity">


    <ImageView
        android:id="@+id/main_image_iv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"/>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal">


        <Button
            android:id="@+id/main_load_btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="onClick"
            android:text="load"/>

        <Button
            android:id="@+id/main_clear_btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="onClick"
            android:text="clear"/>
    </LinearLayout>


</LinearLayout>

4) Activity 作為 Controller 角色的類

package com.example.menglux.mvcproject;

import android.graphics.Bitmap;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;

import com.example.menglux.mvcproject.Model.OnStateChangeListener;

public class MainActivity extends AppCompatActivity implements OnStateChangeListener {

    private ImageView mImageVew;
    private Model mModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mModel  = new Model(this);
        mModel.setOnStateChangeListener(this);  //傳遞監聽物件

        mImageVew = (ImageView) findViewById(R.id.main_image_iv);
        mImageVew.setImageBitmap(mModel.getImage());
    }

    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.main_load_btn:
                mModel.loadImage();
                break;
            case R.id.main_clear_btn:
                mModel.clear();
                break;
        }
    }

    @Override
    public void OnStateChanged(Bitmap image) {
        mImageVew.setImageBitmap(image);
    }
}

4、小結

mvc 作為一種框架模式,本事例是設定一個監聽介面,通過傳遞 傳遞 介面物件 this,來實現資料的傳遞,並不是通過直接呼叫類來實現。

文獻參考:
Android 原始碼設計模式解析與實戰 第二版

本人鄭重宣告,本部落格所編文章、圖片版權歸權利人持有,本博只做學習交流分享所用,不做任何商業用途。訪問者可將本博提供的內容或服務用於個人學習、研究或欣賞,不得用於商業使用。同時,訪問者應遵守著作權法及其他相關法律的規定,不得侵犯相關權利人的合法權利;如果用於商業用途,須徵得相關權利人的書面授權。若文章、圖片的原作者不願意在此展示內容,請及時通知在下,將及時予以刪除。