博主前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住也分享一下给大家, 👉点击跳转到网站
一、首先使用ViewModel写一个小案例,之后在此基础上,结合LiveData一起使用。
1、创建TimerViewModel类
/**
* @Author: ly
* @Date: 2022/9/13
* @Description: 继承ViewModel类,将视图与数据分离
*/
public class TimerViewModel extends ViewModel {
private Timer timer;
private int currentSecond;
/**
* 开始计时
*/
public void startTiming() {
if (timer == null) {
currentSecond = 0;
timer = new Timer();
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
currentSecond++;
if (onTimeChangeListener != null) {
onTimeChangeListener.onTimeChanged(currentSecond);
}
}
};
timer.schedule(timerTask, 1000, 1000);
}
}
/**
* 通过接口的方式,完成对调用者的通知
* 实际上这种方式不是很好,更好的方式是通过LiveData组件来实现
*/
public interface OnTimeChangeListener {
void onTimeChanged(int second);
}
private OnTimeChangeListener onTimeChangeListener;
public void setOnTimeChangeListener(OnTimeChangeListener onTimeChangeListener) {
this.onTimeChangeListener = onTimeChangeListener;
}
@Override
protected void onCleared() {
super.onCleared();
timer.cancel();
}
}
2、在MainActivity中,通过实现接口OnTimeChangeListener ,进行数据变化的监听。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iniComponent();
}
private void iniComponent() {
final TextView textView = findViewById(R.id.textView);
TimerViewModel timerViewModel = new ViewModelProvider(this).get(TimerViewModel.class);
timerViewModel.setOnTimeChangeListener(new TimerViewModel.OnTimeChangeListener() {
@Override
public void onTimeChanged(int second) {
//更新UI界面
runOnUiThread(new Runnable() {
@Override
public void run() {
textView.setText(String.valueOf(second));
}
});
}
});
timerViewModel.startTiming();
}
}
二、将上面的案例,结合LiveData组件一起使用,这样会更方便,减少代码的冗余。 1、首先介绍一下LiveData组件
LiveData是一个可被观察的数据容器类,具体来说,可以将LiveData理解为一个数据的容器,它将数据包装起来,使数据成为被观察者,当该数据发生变化的时候,观察者就能获得通知,我们不需要自己去实现观察者模式,LiveData内部已经默认实现好了,我们只要使用就可以了。
下面我们就用LiveData取代上面所定义的OnTimeChangeListener 接口,完成ViewModel与页面之间的通信。
1、TimerWithLiveDataViewModel 类如下
/**
* @Author: ly
* @Date: 2022/9/1
* @Description: LiveData是一个抽象类,不能直接使用,我们使用它的直接子类MutableLiveData
*/
public class TimerWithLiveDataViewModel extends ViewModel {
//将currentSecond这个字段用MutableLiveData包装起来
private MutableLiveData<Integer> currentSecond;
private Timer timer;
private int second = 0;
public LiveData<Integer> getCurrentSecond() {
if (currentSecond == null) {
currentSecond = new MutableLiveData<>();
}
return currentSecond;
}
/**
* 开始计时
*/
public void startTiming() {
if (timer == null) {
timer = new Timer();
second = 0;
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
currentSecond.postValue(second++);
}
};
timer.schedule(timerTask, 1000, 1000);
}
}
@Override
protected void onCleared() {
super.onCleared();
timer.cancel();
}
}
2、MainActivity类如下
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iniComponent();
}
final TextView textView = findViewById(R.id.textView);
final Button btn = findViewById(R.id.btn);
TimerWithLiveDataViewModel timerWithLiveDataViewModel = new ViewModelProvider(this).get(TimerWithLiveDataViewModel.class);
//得到ViewModel中的LiveData
final MutableLiveData<Integer> liveData = (MutableLiveData<Integer>) timerWithLiveDataViewModel.getCurrentSecond();
//通过LiveData.observe()观察ViewModel中数据的变化
liveData.observe(this, new Observer<Integer>() {
@Override
public void onChanged(Integer integer) {
//收到回调更新UI界面
textView.setText("Time:" + integer);
}
});
//重置计时器
btn.setOnClickListener((v) -> {
//完成对ViewModel中数据的更新
//setValue(T) 必须在主线程中调用 ,
// 而 postValue(T) 既可以在主线程中调用, 也可以在子线程中调用
liveData.setValue(0);
});
//计时开始
timerWithLiveDataViewModel.startTiming();
}
}
以上是ViewModel和LiveData一起使用的最基本用法。
|