1.LiveData初识
LiveData:ViewModel管理要展示的数据(VM层类似于原MVP中的P层),处理业务逻辑,比如调用服务器的登陆接口业务。通过LiveData观察者模式,只要数据的值发生了改变,就会自动通知VIEW层,View层会设置观察者来监听数据的改变。
MVP:P调用M层去获取数据,P回调View层实现的接口,把数据以函数参数的形式传递过去。
2.示例工程
build.gradle要修改下,增加如下配置以开启Databinding:
dataBinding{
enabled = true;
}
2.1View层
布局界面,Alt+Enter可以转成Databinding可以识别的布局。这时识别前的布局。
activity_main.xml。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:gravity="center_horizontal"
android:orientation="vertical">
<EditText
android:layout_marginTop="100dp"
android:id="@+id/edtUserName"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:hint="请输入用户名!" />
<EditText
android:id="@+id/edtPassword"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:hint="请输入密码!" />
<Button
android:id="@+id/btLogin"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:text="登陆"/>
</LinearLayout>
转换后的布局:
<?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>
</data>
<LinearLayout
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:gravity="center_horizontal"
android:orientation="vertical">
<EditText
android:layout_marginTop="100dp"
android:id="@+id/edtUserName"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:hint="请输入用户名!" />
<EditText
android:id="@+id/edtPassword"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:hint="请输入密码!" />
<Button
android:id="@+id/btLogin"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:text="登陆" />
</LinearLayout>
</layout>
MainActivity.java
package com.gaoting.livedatatest.ui;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.databinding.DataBindingUtil;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import com.gaoting.livedatatest.R;
import com.gaoting.livedatatest.databinding.ActivityMainBinding;
import com.gaoting.livedatatest.viewmodel.LoginViewModel;
/***
* View层
*/
public class MainActivity extends AppCompatActivity {
ActivityMainBinding activityMainBinding;
LoginViewModel loginViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activityMainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main);
loginViewModel = new ViewModelProvider(MainActivity.this).get(LoginViewModel.class);
initView();
initListener();
initLiveDataObserver();
}
private void initLiveDataObserver() {
loginViewModel.getStrToken().observe(this, new Observer<String>() {
@Override
public void onChanged(String newToken) {
Toast.makeText(MainActivity.this,"TOKEN="+newToken,Toast.LENGTH_SHORT).show();
}
});
}
private void initListener() {
activityMainBinding.btLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String username = activityMainBinding.edtUserName.getText().toString();
String password = activityMainBinding.edtPassword.getText().toString();
loginViewModel.login(username,password);
}
});
}
private void initView() {
activityMainBinding.edtUserName.setText("test");
activityMainBinding.edtPassword.setText("12345678");
}
}
2.2ViewModel层:
package com.gaoting.livedatatest.viewmodel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import com.gaoting.livedatatest.model.HttpDataSource;
/***
* VM层:
* 1.viewModel用来管理view层(Activity要展示的数据):
* 2.处理业务逻辑,比如对数据进行加工处理,获取HTTP接口数据。
*/
public class LoginViewModel extends ViewModel {
//livedata token string
MutableLiveData<String> strToken = new MutableLiveData<>();
public MutableLiveData<String> getStrToken() {
return strToken;
}
//login
public void login(String username, String password) {
//可能会对密码进行加密等业务逻辑,这里我们忽略。
HttpDataSource httpDataSource = new HttpDataSource();
String token = httpDataSource.login(username,password);
strToken.postValue(token);
}
}
2.3Model层:
package com.gaoting.livedatatest.model;
/***
* 获取网络数据M层
*/
public class HttpDataSource {
//模拟请求网络服务器的登陆业务接口
public String login(String username, String password) {
String token;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
token = "123token";
return token;
}
}