减法、减法、继续减法,之前记录了一半,最近抽时间再补全一下,仅为个人见解~
Android Architecture Components 架构组件
因为一直处于小厂的舒适区中,所以除了自我驱动外,一般根本不会接触到近几年的新技术,不过该庆幸的是 “吾虽未齐头奋进,但从未落地不前” ~
近几年Jetpack组件库被广泛使用,除去Kotlin的compose等相关组件外,我们首先应该掌握的还是可兼容Java Lifecycle、LiveData、ViewModel 组件套 ~
基本认知
其实在学习ViewModel组件前,最好是掌握了Lifecycle和LiveData组件,因为在ViewModel中看到了这俩个组件的影子!
每个人的学习方式有所不同,有的喜欢看视频,有的喜欢看blog,有的喜欢看源码,但是根据常规顺序学一样知识的时候,最先看的应该是 官方文档 - LiveData 、官方文档 - ViewModel
我不太清楚别人是如何理解 LiveData、ViewModel 的,我也不知道这么理解对不对 ?
ViewModel 官网介绍 :ViewModel类旨在以注重生命周期的方式存储和管理界面相关的数据。ViewModel 类让数据可在发生屏幕旋转等配置更改后继续留存。ViewModel 自我理解 :保留数据、视图的意外丢失,支持Activity和依赖该Activity的Fragment共享数据源LiveData 自我理解 :可被观察的数据持有类LiveData+LiveData 自我理解 :ViewModel分解为View、Model,主要通过数据来驱动视图 ,可实时监听数据变化,内部应该采用了观察者模式,这里主要是LiveData特性 ;涉及到生命周期的范围,一般都用到了Lifecycle
基础实现
build.gradle 引入依赖
implementation "android.arch.lifecycle:extensions:1.1.0"
官网示例
注意:此示例为官网中ViewModel的使用示例,尽可借鉴,有个大概印象就好
ViewModel
public class MyViewModel extends ViewModel {
private MutableLiveData<List<User>> users;
public LiveData<List<User>> getUsers() {
if (users == null) {
users = new MutableLiveData<List<User>>();
loadUsers();
}
return users;
}
private void loadUsers() {
}
}
Activity
public class MyActivity extends AppCompatActivity {
public void onCreate(Bundle savedInstanceState) {
MyViewModel model = new ViewModelProvider(this).get(MyViewModel.class);
model.getUsers().observe(this, users -> {
});
}
}
Fragment
public class SharedViewModel extends ViewModel {
private final MutableLiveData<Item> selected = new MutableLiveData<Item>();
public void select(Item item) {
selected.setValue(item);
}
public LiveData<Item> getSelected() {
return selected;
}
}
public class ListFragment extends Fragment {
private SharedViewModel model;
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
itemSelector.setOnClickListener(item -> {
model.select(item);
});
}
}
public class DetailFragment extends Fragment {
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
SharedViewModel model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
model.getSelected().observe(getViewLifecycleOwner(), item -> {
});
}
}
自我演练
既然都说是ViewModel了,肯定是以model为单元进行演练的,但是最后我也加入了类似LiveData单字符串的调用方式 ~
TestModel
这个很常见,可以理解为model、bean这样的实体类,没什么特殊的
package com.example.livedata;
public class TestModel {
public TestModel(String name, int age) {
this.name = name;
this.age = age;
}
public TestModel() {
super();
}
public String name;
public int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
TestViewModel
这个类比较关键,是ViewModel组件实现的主体类;关于以下俩种实现方式的最终效果是一致的,主要区别在于LiveData和MutableLiveData更新数据时的使用方式 ,关于具体区别看我上面提到的 LiveData Blog 就好~
实现方式 1:根据官方示例 获取ViewModel时,返回的是LiveData,导致只能通过类内方法进行设值, 个人不建议这么使用,虽然实现了出口统一,但是使用起来有点麻烦;不过不能一棒子打死,根据自己场景选取实现方式吧~
package com.example.livedata;
import android.util.Log;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
public class TestViewModel extends ViewModel {
private MutableLiveData<TestModel> liveData;
public LiveData<TestModel> getTestViewModel() {
if (liveData == null) {
liveData = new MutableLiveData<TestModel>();
}
return liveData;
}
public void setTestViewModel(TestModel testModel) {
liveData.postValue(testModel);
}
@Override
protected void onCleared() {
super.onCleared();
Log.e("tag","只有ViewModel已经没有任何Activity与之有关联,系统则会调用该方法,你可以在此清理资源");
}
}:
MainActivity
package com.example.livedata;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
public class MainActivity extends AppCompatActivity {
private TestViewModel testViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView mName = findViewById(R.id.tv_test);
testViewModel = ViewModelProviders.of(this).get(TestViewModel.class);
testViewModel.getTestViewModel().observe(this, new Observer<TestModel>() {
@Override
public void onChanged(TestModel testModel) {
mName.setText("姓名:" + testModel.getName() + " - 年龄:" + testModel.age);
}
});
mName.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
testViewModel.setTestViewModel(new TestModel("吾名:Live",19));
}
});
}
}
实现方式 2:根据对LiveData的掌握,我将获取ViewModel的返回类换MutableLiveData, 主要为了方便我自己的灵活调用> <
package com.example.livedata;
import android.util.Log;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
public class TestViewModel extends ViewModel {
private MutableLiveData<TestModel> mutableLiveData;
public MutableLiveData<TestModel> getTestViewModel_Mutable() {
if (mutableLiveData == null) {
mutableLiveData = new MutableLiveData<TestModel>();
}
return mutableLiveData;
}
@Override
protected void onCleared() {
super.onCleared();
Log.e("tag","只有ViewModel已经没有任何Activity与之有关联,系统则会调用该方法,你可以在此清理资源");
}
}
MainActivity
package com.example.livedata;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
public class MainActivity extends AppCompatActivity {
private TestViewModel testViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView mName = findViewById(R.id.tv_test);
testViewModel = ViewModelProviders.of(this).get(TestViewModel.class);
testViewModel.getTestViewModel_Mutable().observe(this, new Observer<TestModel>() {
@Override
public void onChanged(TestModel testModel) {
mName.setText("姓名:" + testModel.getName() + " - 年龄:" + testModel.age);
}
});
mName.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
testViewModel.getTestViewModel_Mutable().postValue(new TestModel("吾名:Live",19));
}
});
}
}
单串演练
上方主要是关于一个model的监听,这里就是仅观察一个字符串的案例,闲的没事儿尝试后记录一下,和LiveData的基本功能有点一样 ~
TestViewModel
package com.example.livedata;
import android.util.Log;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
public class TestViewModel extends ViewModel {
private MutableLiveData<String> stringMutableLiveData;
MutableLiveData<String> getAlone() {
if (stringMutableLiveData == null) {
stringMutableLiveData = new MutableLiveData<>();
}
return stringMutableLiveData;
}
@Override
protected void onCleared() {
super.onCleared();
Log.e("tag","只有ViewModel已经没有任何Activity与之有关联,系统则会调用该方法,你可以在此清理资源");
}
}
MainActivity
package com.example.livedata;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
public class MainActivity extends AppCompatActivity {
private TestViewModel testViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView mName = findViewById(R.id.tv_alone);
testViewModel = ViewModelProviders.of(this).get(TestViewModel.class);
testViewModel.getAlone().observe(this, new Observer<String>() {
@Override
public void onChanged(String data) {
mAlone.setText(data);
}
});
mAlone.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
testViewModel.getAlone().postValue("小小笑话可笑可笑");
}
});
}
}
完整Demo
TestModel
package com.example.livedata;
public class TestModel {
public TestModel(String name, int age) {
this.name = name;
this.age = age;
}
public TestModel() {
super();
}
public String name;
public int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
TestViewModel
package com.example.livedata;
import android.util.Log;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
public class TestViewModel extends ViewModel {
private MutableLiveData<TestModel> liveData;
private MutableLiveData<TestModel> mutableLiveData;
private MutableLiveData<String> stringMutableLiveData;
public LiveData<TestModel> getTestViewModel() {
if (liveData == null) {
liveData = new MutableLiveData<TestModel>();
}
return liveData;
}
public MutableLiveData<TestModel> getTestViewModel_Mutable() {
if (mutableLiveData == null) {
mutableLiveData = new MutableLiveData<TestModel>();
}
return mutableLiveData;
}
public void setTestViewModel(TestModel testModel) {
liveData.postValue(testModel);
}
MutableLiveData<String> getAlone() {
if (stringMutableLiveData == null) {
stringMutableLiveData = new MutableLiveData<>();
}
return stringMutableLiveData;
}
@Override
protected void onCleared() {
super.onCleared();
Log.e("tag", "只有ViewModel已经没有任何Activity与之有关联,系统则会调用该方法,你可以在此清理资源");
}
}
MainActivity
package com.example.livedata;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
public class MainActivity extends AppCompatActivity {
private TestViewModel testViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView mTest = findViewById(R.id.tv_test);
TextView mAlone = findViewById(R.id.tv_alone);
testViewModel = ViewModelProviders.of(this).get(TestViewModel.class);
testViewModel.getTestViewModel_Mutable().observe(this, new Observer<TestModel>() {
@Override
public void onChanged(TestModel testModel) {
mTest.setText("姓名:" + testModel.getName() + " - 年龄:" + testModel.age);
}
});
testViewModel.getAlone().observe(this, new Observer<String>() {
@Override
public void onChanged(String data) {
mAlone.setText(data);
}
});
mTest.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
testViewModel.setTestViewModel(new TestModel("吾名:Live", 19));
}
});
mTest.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
testViewModel.getTestViewModel_Mutable().postValue(new TestModel("吾名:Live", 19));
}
});
mAlone.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
testViewModel.getAlone().postValue("小小笑话可笑可笑");
}
});
}
}
|