最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解Android框架MVVM分析以及使用

 更新時間:2021年04月12日 17:25:27   作者:清風(fēng)伴佳人  
這篇文章主要介紹了詳解Android框架MVVM分析以及使用,對MVVM感興趣的同學(xué),一定要看一下

Android MVVM 分析以及使用

首先我們需要知道什么是MVVM,他的功能和優(yōu)點(diǎn),以及他的缺點(diǎn)。

MVVM是Model-View-ViewModel的簡寫。它本質(zhì)上就是MVC 的改進(jìn)版。MVVM 就是將其中的View 的狀態(tài)和行為抽象化,讓我們將視圖 UI 和業(yè)務(wù)邏輯分開。當(dāng)然這些事 ViewModel 已經(jīng)幫我們做了,它可以取出 Model 的數(shù)據(jù)同時幫忙處理 View 中由于需要展示內(nèi)容而涉及的業(yè)務(wù)邏輯。微軟的WPF帶來了新的技術(shù)體驗(yàn),如Silverlight、音頻、視頻、3D、動畫……,這導(dǎo)致了軟件UI層更加細(xì)節(jié)化、可定制化。同時,在技術(shù)層面,WPF也帶來了 諸如Binding、Dependency Property、Routed Events、Command、DataTemplate、ControlTemplate等新特性。MVVM(Model-View-ViewModel)框架的由來便是MVP(Model-View-Presenter)模式與WPF結(jié)合的應(yīng)用方式時發(fā)展演變過來的一種新型架構(gòu)框架。它立足于原有MVP框架并且把WPF的新特性糅合進(jìn)去,以應(yīng)對客戶日益復(fù)雜的需求變化。

WPF的數(shù)據(jù)綁定與Presentation Model相結(jié)合是非常好的做法,使得開發(fā)人員可以將View和邏輯分離出來,但這種數(shù)據(jù)綁定技術(shù)非常簡單實(shí)用,也是WPF所特有的,所以我們又稱之為Model-View-ViewModel(MVVM)。這種模式跟經(jīng)典的MVP(Model-View-Presenter)模式很相似,除了你需要一個為View量身定制的model,這個model就是ViewModel。ViewModel包含所有由UI特定的接口和屬性,并由一個 ViewModel 的視圖的綁定屬性,并可獲得二者之間的松散耦合,所以需要在ViewModel 直接更新視圖中編寫相應(yīng)代碼。數(shù)據(jù)綁定系統(tǒng)還支持提供了標(biāo)準(zhǔn)化的方式傳輸?shù)揭晥D的驗(yàn)證錯誤的輸入的驗(yàn)證。
在視圖(View)部分,通常也就是一個Aspx頁面。在以前設(shè)計模式中由于沒有清晰的職責(zé)劃分,UI 層經(jīng)常成為邏輯層的全能代理,而后者實(shí)際上屬于應(yīng)用程序的其他層。MVP 里的M 其實(shí)和MVC里的M是一個,都是封裝了核心數(shù)據(jù)、邏輯和功能的計算關(guān)系的模型,而V是視圖(窗體),P就是封裝了窗體中的所有操作、響應(yīng)用戶的輸入輸出、事件等,與MVC里的C差不多,區(qū)別是MVC是系統(tǒng)級架構(gòu)的,而MVP是用在某個特定頁面上的,也就是說MVP的靈活性要遠(yuǎn)遠(yuǎn)大于MVC,實(shí)現(xiàn)起來也極為簡單。
我們再從IView這個interface層來解析,它可以幫助我們把各類UI與邏輯層解耦,同時可以從UI層進(jìn)入自動化測試(Unit/Automatic Test)并提供了入口,在以前可以由WinForm/Web Form/MFC等編寫的UI是通過事件Windows消息與IView層溝通的。WPF與IView層的溝通,最佳的手段是使用Binding,當(dāng)然,也可以使用事件;Presenter層要實(shí)現(xiàn)IView,多態(tài)機(jī)制可以保證運(yùn)行時UI層顯示恰當(dāng)?shù)臄?shù)據(jù)。比如Binding,在程序中,你可能看到Binding的Source是某個interface類型的變量,實(shí)際上,這個interface變量引用著的對象才是真正的數(shù)據(jù)源。
MVC模式大家都已經(jīng)非常熟悉了,在這里我就不贅述,這些模式也是依次進(jìn)化而形成MVC—>MVP—>MVVM。有一句話說的好:當(dāng)物體受到接力的時候,凡是有界面的地方就是最容易被撕下來的地方。因此,IView作為公共視圖接口約束(契約)的一層意思;View則能傳達(dá)解耦的一層意思。

設(shè)計模式

因?yàn)閃PF技術(shù)出現(xiàn),從而使MVC架構(gòu)模式有所改進(jìn),MVVM 模式便是使用的是數(shù)據(jù)綁定基礎(chǔ)架構(gòu)。它們可以輕松構(gòu)建UI的必要元素。
可以參考The Composite Application Guidance for WPF(prism)
View綁定到ViewModel,然后執(zhí)行一些命令在向它請求一個動作。而反過來,ViewModel跟Model通訊,告訴它更新來響應(yīng)UI。這樣便使得為應(yīng)用構(gòu)建UI非常的容易。往一個應(yīng)用程序上貼一個界面越容易,外觀設(shè)計師就越容易使用Blend來創(chuàng)建一個漂亮的界面。同時,當(dāng)UI和功能越來越松耦合的時候,功能的可測試性就越來越強(qiáng)。
在MVP模式中,為了讓UI層能夠從邏輯層上分離下來,設(shè)計師們在UI層與邏輯層之間加了一層interface。無論是UI開發(fā)人員還是數(shù)據(jù)開發(fā)人員,都要尊重這個契約、按照它進(jìn)行設(shè)計和開發(fā)。這樣,理想狀態(tài)下無論是Web UI還是Window UI就都可以使用同一套數(shù)據(jù)邏輯了。借鑒MVP的IView層,養(yǎng)成習(xí)慣。View Model聽起來比Presenter要貼切得多;會把一些跟事件、命令相關(guān)的東西放在MVC的'C',或者是MVVM的'Vm'。

MVVM優(yōu)點(diǎn)

MVVM模式和MVC模式一樣,主要目的是分離視圖(View)和模型(Model),有幾大優(yōu)點(diǎn)

  1. 低耦合。視圖(View)可以獨(dú)立于Model變化和修改,一個ViewModel可以綁定到不同的"View"上,當(dāng)View變化的時候Model可以不變,當(dāng)Model變化的時候View也可以不變。
  2. 可重用性。你可以把一些視圖邏輯放在一個ViewModel里面,讓很多view重用這段視圖邏輯。
  3. 獨(dú)立開發(fā)。開發(fā)人員可以專注于業(yè)務(wù)邏輯和數(shù)據(jù)的開發(fā)(ViewModel),設(shè)計人員可以專注于頁面設(shè)計,使用Expression Blend可以很容易設(shè)計界面并生成xaml代碼。
  4. 可測試。界面素來是比較難于測試的,測試可以針對ViewModel來寫。

MVVM控件

使用MVVM來開發(fā)用戶控件。由于用戶控件在大部分情況下不涉及到數(shù)據(jù)的持久化,所以如果將M純粹理解為DomainModel的話,使用MVVM模式來進(jìn)行自定義控件開發(fā)實(shí)際上可以省略掉M,變成了VVM

MVVM的核心是databidning 這是一個用于數(shù)據(jù)雙向綁定的,他的強(qiáng)大之處,出了雙向綁定之外,還可以代替butterknife。眾所周知butterknife需要對每一個控件進(jìn)行單獨(dú)的綁定,這樣子不但非常的費(fèi)時間,而且會導(dǎo)致代碼看起來極其的復(fù)雜。下面上圖展示一下實(shí)際的差距。

這是butterknife這個樣子只是進(jìn)行了,綁定但是在用的時候還是不夠方便因?yàn)槟闳ヒ鶕?jù)你的id去寫出,對應(yīng)的id方可進(jìn)行操作。

這個databinding的是綁定聲明,使用起來是這樣子的

databinding后面直接點(diǎn)就可以,選擇綁定頁面的中的控件。
而且他的強(qiáng)大之處就是,databinding綁定之后就相當(dāng)于一個viewgroup。這個在適配器中或者自定義頁面的情況下極大地減少了,代碼量。而且更不易出錯。非常的穩(wěn)定。
那么可能會有人問,既然使用了kotlin,那么我為什么還有使用databinding呢,沒錯總是有些杠精要和你杠一下,kotlin中的自帶的id調(diào)用,是不錯的。除非的你每個id開通都不重復(fù)否則。

那你就等根據(jù)后面的所屬的activity慢慢選吧,而且kotlin綁定的控件,無法傳遞內(nèi)存地址,你想把這個控件傳到適配器里,那是不可能的。

接下來我們就說一下databinding的數(shù)據(jù)綁定,databinding自帶的數(shù)據(jù)雙向綁定,首先在使用之間,需要在gradle引入

這就就是打開databinding,那么如果使用數(shù)據(jù)綁定

首先使用databinding時 布局必須以開頭,結(jié)尾。然后就可以在代碼中綁定以開頭結(jié)尾的文件了。

然后在布局中聲明的id,

就可以直接調(diào)用

現(xiàn)在只是綁定了布局,還并沒有綁定數(shù)據(jù),數(shù)據(jù)綁定可以使bean也可以直接是數(shù)據(jù)。下面是數(shù)據(jù)的綁定,可以直接在

也可以在代碼中聲明一個數(shù)據(jù)源,例如:

這個要在標(biāo)簽中聲明。type就是他的類型。然后在代碼中綁定這個數(shù)據(jù)

然后就可以直接在布局中設(shè)置數(shù)據(jù)了

這個樣子已經(jīng)是實(shí)現(xiàn)了,datanbinding的雙向綁定,但是還不是 所有,當(dāng)數(shù)據(jù)刷新時,我們通常需要手動刷新或者在代碼里重新賦值,但是databinding是不需要的,你只需要在bean中實(shí)現(xiàn)一個生命就可以,例如

在類的后面繼承BaseObservable(是每一個類,一個bean中可能有多個類),

然后在get方法上面聲明@Bindable,之后就可以了。當(dāng)數(shù)據(jù)發(fā)生改變,綁定的數(shù)據(jù)就會自動改變,是不是很強(qiáng)大?,F(xiàn)在只是介紹了databinding,接下來我們來看看MVVM。
MVVM分為model,view,modelView(簡稱vm),所以我們在使用是就可以像mvp一樣分開文件,具有解耦效果,為了保證代碼的安全性,我們分別使用modelIpl,VmIPL,就是讓他們繼承自接口,保證文件的安全性,下面開始實(shí)戰(zhàn)操作。
首先是model

interface MassageModel {
    fun initData(context: Context?,activity: Activity?,page:Int,size :Int,stringCallback: StringCallback)
    fun upData(context: Context?,activity: Activity?,page:Int,size :Int,stringCallback: StringCallback)
    fun LoadMoreData(context: Context?,activity: Activity?,page:Int,size :Int,stringCallback: StringCallback)
    fun readAll(context: Context?,activity: Activity?,stringCallback: StringCallback)
    fun delectSelect(context: Context?,activity: Activity?,ids: String,stringCallback: StringCallback)
    fun updateUerNews(context: Context?,activity: Activity?,id:Int,stringCallback: StringCallback)


}

然后實(shí)現(xiàn)model的接口modelIpl

class MassageModelIpl:MassageModel {
    override fun initData(context: Context?, activity: Activity?, page: Int, size: Int, stringCallback: StringCallback) {
      NetControl(context, activity).queryUerList(page,size,stringCallback)
    }

    override fun upData(context: Context?, activity: Activity?, page: Int, size: Int, stringCallback: StringCallback) {
        NetControl(context, activity).queryUerList(page,size,stringCallback)
    }

    override fun LoadMoreData(context: Context?, activity: Activity?, page: Int, size: Int, stringCallback: StringCallback) {
        NetControl(context, activity).queryUerList(page,size,stringCallback)
    }

    override fun readAll(context: Context?, activity: Activity?, stringCallback: StringCallback) {
        NetControl(context, activity).uerNewsReaded(stringCallback)
    }

    override fun delectSelect(context: Context?, activity: Activity?, ids: String, stringCallback: StringCallback) {
        NetControl(context, activity).deleteUerList(ids,stringCallback)
    }

    override fun updateUerNews(context: Context?, activity: Activity?, id: Int, stringCallback: StringCallback) {
        NetControl(context, activity).updateUerNews(id,stringCallback)

    }
}

然后是ViewModelListener(Vm)

Vm

class MassageVm(activity: Activity, context: Context, massageBinding: ActivityMassageBinding,
                layoutInflater: LayoutInflater) : MassageListener {
    var activity: Activity
    var context: Context
    var massageBinding: ActivityMassageBinding
    var massageModelIpl: MassageModelIpl
    var massageBean: MassageBean? = null;
    var massageAdapter: MassageAdapter? = null
    var layoutInflater: LayoutInflater
   

    init {
        this.context = context
        this.layoutInflater = layoutInflater
        this.activity = activity
        this.massageBinding = massageBinding
        massageModelIpl = MassageModelIpl()
       

    }

    /**
     * 加載第一次的數(shù)據(jù)
     */
    override fun initData() {
        
    }

    /**
     * 加載適配器
     */
    private fun initListViewData() {
       
    }

    /**
     * 下拉刷新
     */
    override fun update() {
       
    }

    /**
     * 上拉加載
     */
    override fun loadMore() {
        
    }

    /**
     * 全部已讀
     */
    override fun readAll() {
       
    }

    /**
     * 刪除選中
     */
    override fun delectSelect() {
       
    }

    override fun ReadSimple(id: Int) {
       

    }

    /**
     * dialog提示
     */
    private fun ShowToast(s: String, type: Int) {
       
    }
}

最后就是講view和Vm綁定
就是activity或者Fragment

class MassageActivity : BaseMVVMActivity() {
    lateinit var activityMassageBinding: ActivityMassageBinding
    lateinit var massageVm: MassageVm
    override fun InitNew() {

    }

    override fun setVM() {
        massageVm = MassageVm(this, this, activityMassageBinding, layoutInflater)
    }

    override fun InitData() {
        massageVm.initData()
    }

    override fun SetLayout(): Int {
        return R.layout.activity_massage
    }

    override fun FindView() {

    }

    override fun SetListener() {
        activityMassageBinding.listView.setOnLoadMoreListener {
            massageVm.loadMore()
        }

        activityMassageBinding.listView.setOnRefreshListener {
            massageVm.update()
        }

        activityMassageBinding.btnSelectIsRead.setOnClickListener {
            massageVm.readAll()
        }
        activityMassageBinding.btnSelectDelete.setOnClickListener {
            massageVm.delectSelect()
        }
    }

    override fun SetBindingLayout() {
        activityMassageBinding = DataBindingUtil.setContentView(this, R.layout.activity_massage)
    }
    override fun onBackPressed() {
        val intent = Intent(this, MainActivity::class.java)
        startActivity(intent)
        overridePendingTransition(R.anim.fade_in, android.R.anim.slide_out_right)
        finish()

    }

    /**
     * 返回
     *
     * @param view
     */
    fun btnPrevious(view: View?) {
        onBackPressed()
    }
}

需要說明一個fragment/adapter/viewgroup中需要一個layoutInflater這個就決定了activity的綁定方式和fragment的綁定方式不是相同的,下面說一個fragment中的綁定方式。(adapter和viewgroup的也是相同的方法)

   var itemMyorderList1Binding: ItemMyorderList1Binding =
                DataBindingUtil.inflate(layoutInflater,
                        R.layout.item_myorder_list1, null, false)

ItemMyorderList1Binding 這個就是你布局的名字后面加上一個binding。
最后送上套簡單的activity和fragment的封裝

public abstract class BaseMVVMActivity extends AppCompatActivity {


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        DataBindingUtil.setContentView(this, SetLayout());
        SetBindingLayout();
        FindView();
        setVM();
        InitNew();
        InitData();
        SetListener();
    }

    public void SetBindingLayout() {

    }

    protected abstract void setVM();

    protected abstract int SetLayout();

    protected abstract void FindView();

    protected abstract void InitNew();

    protected abstract void InitData();

    protected abstract void SetListener();


}
public abstract class BaseMVVMFragment extends Fragment {
    LayoutInflater flater;


    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        flater = inflater;
        View view = SetView();
        findView();
        initVM();
        initData();
        SetListener();

        return view;

    }

    public void initData() {

    }


    protected abstract View SetView();

    protected abstract void initVM();

    protected abstract void findView();

    protected abstract void SetListener();


    public LayoutInflater GetInflater() {
        return flater;
    }

}

以上就是詳解Android框架MVVM分析以及使用的詳細(xì)內(nèi)容,更多關(guān)于Android框架MVVM使用的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Android時光軸實(shí)現(xiàn)淘寶物流信息瀏覽效果

    Android時光軸實(shí)現(xiàn)淘寶物流信息瀏覽效果

    這篇文章主要為大家詳細(xì)介紹了Android時光軸實(shí)現(xiàn)淘寶物流信息瀏覽效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • Android中的存儲詳解

    Android中的存儲詳解

    大家好,本篇文章主要講的是Android中的存儲詳解,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2022-01-01
  • 詳解Android中Application設(shè)置全局變量以及傳值

    詳解Android中Application設(shè)置全局變量以及傳值

    這篇文章主要介紹了詳解Android中Application設(shè)置全局變量以及傳值的相關(guān)資料,希望通過本文大家能夠理解掌握這部分內(nèi)容,需要的朋友可以參考下
    2017-09-09
  • Android平臺預(yù)置GMS包后關(guān)機(jī)鬧鐘失效問題及解決方法

    Android平臺預(yù)置GMS包后關(guān)機(jī)鬧鐘失效問題及解決方法

    這篇文章主要介紹了Android平臺預(yù)置GMS包后,關(guān)機(jī)鬧鐘失效,本文給大家分享問題原因及解決方法,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-09-09
  • Android Handler內(nèi)存泄漏原因及解決方案

    Android Handler內(nèi)存泄漏原因及解決方案

    這篇文章主要介紹了Android Handler內(nèi)存泄漏原因及解決方案,幫助大家更好的理解和利用Android進(jìn)行開發(fā),感興趣的朋友可以了解下
    2021-02-02
  • Android仿QQ好友詳情頁下拉頂部圖片縮放效果

    Android仿QQ好友詳情頁下拉頂部圖片縮放效果

    這篇文章主要為大家詳細(xì)介紹了Android仿QQ好友詳情頁下拉頂部圖片縮放效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • Kotlin by關(guān)鍵字作用及使用介紹

    Kotlin by關(guān)鍵字作用及使用介紹

    Kotlin 中的 by 關(guān)鍵字在 Java 中是沒有的,這使我對它感到非常陌生。Kotlin 中為什么要新增 by 關(guān)鍵字呢?by 關(guān)鍵字在 Kotlin 中是如何使用的?本文會介紹 by 關(guān)鍵字的使用分類,具體的示例,Kotlin 內(nèi)置的 by 使用,希望能夠幫助到大家
    2022-10-10
  • Android課程表界面布局實(shí)現(xiàn)代碼

    Android課程表界面布局實(shí)現(xiàn)代碼

    這篇文章主要介紹了Android課程表界面布局實(shí)現(xiàn)代碼,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-10-10
  • 詳解Android壁紙服務(wù)的啟動過程

    詳解Android壁紙服務(wù)的啟動過程

    你有設(shè)置過手機(jī)的壁紙嗎,你知道壁紙是什么樣的程序它是怎么在后臺運(yùn)行的嗎?這篇文章主要介紹了詳解Android系統(tǒng)壁紙服務(wù)的啟動過程
    2021-08-08
  • Android拍照和獲取相冊圖片

    Android拍照和獲取相冊圖片

    這篇文章主要為大家詳細(xì)介紹了Android拍照和獲取相冊圖片的實(shí)現(xiàn)代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-08-08

最新評論

长泰县| 斗六市| 平遥县| 玛多县| 溧水县| 依安县| 临邑县| 丹凤县| 商丘市| 和林格尔县| 清流县| 易门县| 仁布县| 临城县| 开江县| 鄂伦春自治旗| 南充市| 新宾| 佛冈县| 泰顺县| 宁国市| 星子县| 内乡县| 诸暨市| 白山市| 巴彦县| 盖州市| 五峰| 内江市| 耿马| 杭州市| 蓬安县| 江门市| 阜新| 松潘县| 海口市| 罗田县| 高平市| 平罗县| 沿河| 亳州市|