ViewModel的基本使用

目录

  • 一、基本使用
  • 二、ViewModel + DataBinding + LiveData结合使用
    • 1. java版本
    • 2. kotlin版本

ViewModel的职责就是保证View层中数据的稳定性

一、基本使用

在app目录下build.gradle导入ViewModel依赖

implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'

MyViewModel.kt

package com.example.myviewmodel

import androidx.lifecycle.ViewModel

class MyViewModel : ViewModel() {

    // 数据放这 进行横竖屏切换不会丢失
    var number : Int = 0
}

MainActivity.kt

package com.example.myviewmodel

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.lifecycle.ViewModelProvider
// Kotlin的绑定机制
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

    // 数据放这 进行横竖屏切换会丢失
    // var number : Int = 0

    private lateinit var myViewModel: MyViewModel
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // myViewModel = MyViewModel()  // 不能之间实例化,因为这样写系统就不可控了

        // 旧版本的写法(扩展性不强)
        // ViewModelProviders.of(this).get(MyViewModel::class.java)

        // this == ViewModelStoreOwner接口
        myViewModel = ViewModelProvider(this, ViewModelProvider.NewInstanceFactory())
            .get(MyViewModel::class.java)  // 通过反射来加载Java的class

        // Kotlin的绑定机制
        tv_number.text = "${myViewModel.number}"

        bt.setOnClickListener {
            tv_number.text = "${++myViewModel.number}"
        }

    }
}

  数据存放在ViewModelStore类中,该类有一个Map存储,value为ViewModel,该ViewModel存放相关的具体数据,横竖屏切换保证ViewModelStore是同一个对象。

二、ViewModel + DataBinding + LiveData结合使用

1. java版本

在app目录下的build.gradle导入相关的依赖包

apply plugin: 'com.android.application'

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.3"

    defaultConfig {
        applicationId "com.example.jetpack_java2"
        minSdkVersion 26
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

    // dataBinding引入方式
    // 方式一
    dataBinding {
        enabled  true
    }
    // 方式二
    // dataBinding.enabled = true

}

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

    // ViewModel依赖
    implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
    
}

activity_main.xml





    
        
    

    
    

        

        
        

        
        

            
            

                

MainViewModel.java

package com.example.jetpack_java2;

import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;

import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.MutableLiveData;

/**
 * AndroidViewModel 与 ViewModel的区别是 AndroidViewModel自带application环境
 */
public class MainViewModel extends AndroidViewModel {

    // 传统方式的数据
    // private String phoneInfo = "";  // 目前无法实现感应功能

    // 实现感应功能 LiveData + DataBinding
    private MutableLiveData phoneInfo;

    // 环境
    private Context mContext;


    public MainViewModel(@NonNull Application application) {
        super(application);
        mContext = application;
    }

    // 把数据暴露出去 给布局用
    public MutableLiveData getPhoneInfo() {
        if (phoneInfo == null) {
            phoneInfo = new MutableLiveData<>();

            // 设置默认值
            phoneInfo.setValue("");
        }
       return phoneInfo;
    }

    /**
     * 输入
     * @param number
     */
    public void appendNumber(String number) {
        phoneInfo.setValue(phoneInfo.getValue() + number);
    }

    /**
     * 删除
     */
    public void backspaceNumber() {
       int length = phoneInfo.getValue().length();
       if (length > 0) {
           phoneInfo.setValue(phoneInfo.getValue().substring(0, length - 1));
       }
    }

    /**
     * 清空
     */
    public void clear() {
        phoneInfo.setValue("");
    }

    /**
     * 拨打
     */
    public void callPhone() {
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_CALL);
        intent.setData(Uri.parse("tel:" + phoneInfo.getValue()));
        // 非Activity启动拨号 或者是 非Activity启动任何的  startActivity都会崩溃
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        mContext.startActivity(intent);
    }
}

MainActivity.java

package com.example.jetpack_java2;

import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import androidx.lifecycle.ViewModelProvider;
import androidx.lifecycle.ViewModelProviders;

import android.os.Bundle;
import android.view.View;

import com.example.jetpack_java2.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity {
    private ActivityMainBinding dataBinding;   // DataBinding初始化
    private MainViewModel mainViewModel;       // MainViewModel初始化

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // setContentView(R.layout.activity_main);
        dataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);

        // 旧版本的写法
        // mainViewModel = ViewModelProviders.of(this).get(MainViewModel.class);

        // 下面是新版本的写法
        // 如果MainViewModel extends ViewModel
        // mainViewModel = new ViewModelProvider(this,
        //      new ViewModelProvider.NewInstanceFactory()).get(MainViewModel.class);

        // 如果MainViewModel extends AndroidViewModel
        mainViewModel = new ViewModelProvider(getViewModelStore(),
                new ViewModelProvider.AndroidViewModelFactory(getApplication())).get(MainViewModel.class);

        dataBinding.setVm(mainViewModel);

        dataBinding.setLifecycleOwner(this);  // DataBinding与LiveData建立感应
    }
}

AndroidManifest.xml




    
    

    

    
        
            
                

                
            
        
    


2. kotlin版本

MainViewModel.kt

package com.example.jetpack_kotlin

import android.app.Application
import android.content.Context
import android.content.Intent
import android.net.Uri
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MutableLiveData

class MainViewModel(application : Application) : AndroidViewModel(application) {

    // LiveData数据(有感应)
    val phoneInfo by lazy { MutableLiveData() }

    init {
        phoneInfo.value = "" // 设置默认值
    }

    // 定义一个环境
    var mContext : Context = application

    /**
     * 输入
     */
    fun appendNumber(number : String) {
        phoneInfo.value = phoneInfo.value + number
    }

    /**
     * 删除
     */
    fun backspaceNumberr() {
        var length = phoneInfo.value?.length ?: 0
        if (length > 0) {
            phoneInfo.value = phoneInfo.value?.substring(0, length - 1)
        }
    }

    /**
     * 清空
     */
    fun clear() {
        phoneInfo.value = ""
    }

    /**
     * 拨号
     */
    fun callPhone() {
        var intent = Intent()
        intent.action = Intent.ACTION_CALL
        intent.data = Uri.parse("tel:" + phoneInfo.value)
        intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
        mContext.startActivity(intent)
    }
}

MainActivity.kt

package com.example.jetpack_kotlin

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.ViewModelProvider
import com.example.jetpack_kotlin.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {

    var binding : ActivityMainBinding ?= null
    var viewModel : MainViewModel ?= null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // setContentView(R.layout.activity_main)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)

        viewModel = ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory(application))
            .get(MainViewModel::class.java)

        binding?.vm = viewModel

        // DataBinding 与 LiveData 建立感应
        binding?.lifecycleOwner = this

    }
}

你可能感兴趣的:(Android,kotlin,ViewModel)