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存储
在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
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
}
}