MVP 的实现参考前一篇: https://blog.csdn.net/whjk20/article/details/107213294

MVVM 的实现中, Model 部分仍然不变, 使用ViewModel 代替了Presenter, 并且修改了布局文件

1. ViewModel 

package com.example.tictactoe.mvvm.viewmodel


import androidx.databinding.BaseObservable
import androidx.databinding.ObservableArrayMap
import androidx.databinding.ObservableField
import com.example.tictactoe.mvvm.model.Board

class TicTacToeViewModel : BaseObservable {
    private var model: Board? = null

    // ViewModel 充当Presenter 的角色
    // 把VIEW 和数据绑定, 数据改变通知VIEW 更新(通知操作由ObservableXXX 执行)
    // 好:把更新UI 的操作从Activity 中抽离处理,使得Activity 更加简洁(职责单一原因),仅做初始化
    // 同时减少和Activity的耦合性
    var cells = ObservableArrayMap<String, String>()
    var winner = ObservableField<String>()


    constructor() {
        model = Board()

    }

    fun onButtonSelected(row: Int, col: Int) {
        var playerThatMoved = model?.mark(row, col);

        playerThatMoved?.let{cells["" + row + col] = it.toString()}
        model?.winner?.let { winner.set(it.toString())}
    }

    fun onResetSelected() {
        winner.set(null)
        cells.clear()

        model!!.restart()
    }
}

2. 布局文件

<?xml version="1.0" encoding="utf-8"?>

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <import
            type="android.view.View" />
        <variable
            name="ticTacToeViewModel"
            type="com.example.tictactoe.mvvm.viewmodel.TicTacToeViewModel" />
    </data>

    <LinearLayout
        android:id="@+id/tictactoe"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_horizontal"
        android:orientation="vertical"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingBottom="@dimen/activity_vertical_margin"
        tools:context=".mvp.view.TicTacToeMVPActivity">

        <GridLayout
            android:id="@+id/buttonGrid"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:columnCount="3"
            android:rowCount="3">

            <Button
                style="@style/tictactoebutton"
                android:onClick="@{() -> ticTacToeViewModel.onButtonSelected(0, 0)}"
                android:text='@{ticTacToeViewModel.cells["00"]}' />

            <Button
                style="@style/tictactoebutton"
                android:onClick="@{() -> ticTacToeViewModel.onButtonSelected(0, 1)}"
                android:text='@{ticTacToeViewModel.cells["01"]}' />

            <Button

                style="@style/tictactoebutton"
                android:onClick="@{() -> ticTacToeViewModel.onButtonSelected(0, 2)}"
                android:text='@{ticTacToeViewModel.cells["02"]}' />

            <Button
                android:id="@+id/button10"
                style="@style/tictactoebutton"
                android:onClick="@{() -> ticTacToeViewModel.onButtonSelected(1, 0)}"
                android:text='@{ticTacToeViewModel.cells["10"]}' />

            <Button
                style="@style/tictactoebutton"
                android:onClick="@{() -> ticTacToeViewModel.onButtonSelected(1, 1)}"
                android:text='@{ticTacToeViewModel.cells["11"]}' />

            <Button
                style="@style/tictactoebutton"
                android:onClick="@{() -> ticTacToeViewModel.onButtonSelected(1, 2)}"
                android:text='@{ticTacToeViewModel.cells["12"]}' />

            <Button
                style="@style/tictactoebutton"
                android:onClick="@{() -> ticTacToeViewModel.onButtonSelected(2, 0)}"
                android:text='@{ticTacToeViewModel.cells["20"]}' />

            <Button
                style="@style/tictactoebutton"
                android:onClick="@{() -> ticTacToeViewModel.onButtonSelected(2, 1)}"
                android:text='@{ticTacToeViewModel.cells["21"]}' />

            <Button
                style="@style/tictactoebutton"
                android:onClick="@{() -> ticTacToeViewModel.onButtonSelected(2, 2)}"
                android:text='@{ticTacToeViewModel.cells["22"]}' />

        </GridLayout>

        <LinearLayout
            android:id="@+id/winnerPlayerViewGroup"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center"
            android:orientation="vertical"
            android:visibility="@{ticTacToeViewModel.winner != null ? View.VISIBLE: View.GONE}"
            tools:visibility="visible">

            <TextView
                android:id="@+id/winnerPlayerLabel"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="20dp"
                android:textSize="40sp"
                tools:text="@{ticTacToeViewModel.winner}" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Winner"
                android:textSize="30sp" />

        </LinearLayout>
    </LinearLayout>

</layout>

3. Activity 

class TicTacToeMVVMActivity : AppCompatActivity() {

    companion object {
        const val TAG = "TicTacToeMVPActivity"
    }

    private var viewModel = TicTacToeViewModel()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        var dataBinding
                = DataBindingUtil.setContentView<ActivityTictactoeMvvmBinding>(this, R.layout.activity_tictactoe_mvvm)
        dataBinding.ticTacToeViewModel = viewModel
    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.reset_menu, menu)
        return super.onCreateOptionsMenu(menu)
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.design_reset -> {
                viewModel.onResetSelected()
                return true
            }
        }
        return super.onOptionsItemSelected(item)
    }

}

 

本文地址:https://blog.csdn.net/whjk20/article/details/107213445