LiveData和ObservableField双向绑定实现登录功能(附源码)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

      提到双向绑定,就不得不提DataBingding,在android中,讲究视图分离,布局文件通常只负责UI控件的布局工作,页面通过setContentView方法关联布局文件,最通过UI控件的id找到控件,接着在页面中通过代码对控件进行操作,其实这也是一种最基本的MVC模式,随着业务的庞大,activity扮演了controller和view的工作,所以后来推出了MVP,MVVM模式,其中的厉害关系可以参考这篇文章,讲的尤为详细:
MVC、MVP、MVVM,我到底该怎么选?
Google在2015年I/O大会提出DataBinding,DataBinding的出现让布局文件承担了原本属于页面的工作,而LiveData和ObservableField其实就是可观察类,事实上二者可以互相替换使用,二者的区别在于:

  1. ObservableField只有在数据发生改变时UI才会收到通知,而LiveData不同,只要你postValue或者setValue,UI都会收到通知,不管数据有无变化。
  2. LiveData能感知Activity的生命周期,并在其关联的生命周期遭到销毁后进行自我清理,避免了内存泄漏。
    在这里插入图片描述

一、LiveData实现双向绑定

关于retrofit的封装可以参考上篇文章直接使用。
LiveData+retrofit封装(Java版本)附源码

二、使用步骤

1.引入库

 buildFeatures{
    
    
        dataBinding = true
    }

2.用LiveData观察接口,替代Call

   @GET("index/login")
    LiveData<LoginEntity> loginLiveData(
            @Query("username") String username,
            @Query("encryptPwd") String encryptPwd
    );

3.写model类

public class LiveDataLoginModel {
    
    
    private String username;
    private String encryptPwd;

    public LiveDataLoginModel(String username, String encryptPwd) {
    
    
        this.username = username;
        this.encryptPwd = encryptPwd;
    }

    public String getUsername() {
    
    
        return username;
    }

    public void setUsername(String username) {
    
    
        this.username = username;
    }

    public String getEncryptPwd() {
    
    
        return encryptPwd;
    }

    public void setEncryptPwd(String encryptPwd) {
    
    
        this.encryptPwd = encryptPwd;
    }
}

4.创建LiveData的ViewModel类

public class LiveDataViewModel extends ViewModel {
    
    

    //将字段用MutableLiveData包装
    public MutableLiveData<String> username = new MutableLiveData<>();
    public MutableLiveData<String> encryptPwd = new MutableLiveData<>();

    private MutableLiveData<LiveDataLoginModel> loginModelMutableLiveData;

    //初始化获取相关LiveData对象
    public MutableLiveData<LiveDataLoginModel> getLoginModelMutableLiveData() {
    
    
        if (loginModelMutableLiveData == null) {
    
    
            loginModelMutableLiveData = new MutableLiveData<>();
        }
        return loginModelMutableLiveData;
    }

    @Override
    protected void onCleared() {
    
    
        super.onCleared();
    }

      //    定义点击事件
    public void LiveDataOnClick(View view) {
    
    
        LiveDataLoginModel liveDataLoginModel = new LiveDataLoginModel(username.getValue(), encryptPwd.getValue());
        //postValue和setValue区别,postValue()方法用在非UI线程,setValue用在UI线程,通过LiveData.postValue/setValue方法来修改LiveData包装的数据
        loginModelMutableLiveData.postValue(liveDataLoginModel);
    }

    //返回retrofit接口数据
    public LiveData<LoginEntity> getLiveDataLoginEntity() {
    
    
        return ApiService.create(Api.class).loginLiveData(username.getValue(), RxTool.Md5(encryptPwd.getValue()));
    }
}

5.修改布局文件,引入ViewModel

将最外层改为 layout布局,通过 variable引入ViewModel,将Button的 onClick属性改为:

 <data>

        <variable
            name="liveDataViewModel"
            type="com.example.mvvmgithub.viewmodel.LiveDataViewModel" />
    </data>
    
    
 android:onClick="@{(v)->liveDataViewModel.LiveDataOnClick(v)}"

6.修改LiveDataActivity,绑定ViewModel

activityLiveDataBinding = DataBindingUtil.setContentView(this, R.layout.activity_live_data);
         //通过ViewModelProvider得到ViewModel
        liveDataViewModel = new ViewModelProvider(this).get(LiveDataViewModel.class);
        activityLiveDataBinding.setLiveDataViewModel(liveDataViewModel);

然后通过LiveData.observer方法对所包装的数据进行观察

     //得到ViewModel中的LiveData
        final MutableLiveData<LiveDataLoginModel> liveData = liveDataViewModel.getLoginModelMutableLiveData();
        //liveData.observe()观察ViewModel中数据的变化
        liveData.observe(this, new Observer<LiveDataLoginModel>() {
    
    
            @Override
            public void onChanged(LiveDataLoginModel liveDataLoginModel) {
    
    
                if (!TextUtils.isEmpty(activityLiveDataBinding.psdNicknameEdit.getText()) && !TextUtils.isEmpty(activityLiveDataBinding.psdEdit.getText())) {
    
    
                    LiveData<LoginEntity> liveDataLoginEntity = liveDataViewModel.getLiveDataLoginEntity();
                    liveDataLoginEntity.observe(LiveDataActivity.this, new Observer<LoginEntity>() {
    
    
                        @Override
                        public void onChanged(LoginEntity loginEntity) {
    
    
                        
                        }
                    });
                }
            }
        });

至此LiveData双向绑定功能已经实现,接下来简单介绍ObservableField双向绑定,由于我的retrofit是用LiveData封装,所以此处直接使用Call进行观察

  1. List item

Api如下:

    @GET("index/login")
    Call<LoginEntity> loginObservableField(
            @Query("username") String username,
            @Query("encryptPwd") String encryptPwd
    );
  1. 修改model类
public class ObservableFieldLoginModel {
    
    
 public String username;
 public String encryptPwd;
}

3.修改ViewModel类

public class ObservableFieldViewModel extends ViewModel {
  private ObservableField<ObservableFieldLoginModel> observableFieldLoginModelObservableField;
  private static final String TAG = "PsdViewModel";

  public ObservableFieldViewModel() {
      ObservableFieldLoginModel ObservableFieldLoginModel = new ObservableFieldLoginModel();
      observableFieldLoginModelObservableField = new ObservableField<>();
      observableFieldLoginModelObservableField.set(ObservableFieldLoginModel);
  }

  public String getNickName() {
      Log.e(TAG, "getNickName()");
      return observableFieldLoginModelObservableField.get().username;
  }

  public String setNickName(String username) {
      Log.e(TAG, "setNickName()->" + username);
      return observableFieldLoginModelObservableField.get().username = username;
  }

  public String getPassword() {
      Log.e(TAG, "getPassword()");
      return observableFieldLoginModelObservableField.get().encryptPwd;
  }

  public String setPassword(String encryptPwd) {
      Log.e(TAG, "setPassword()->" + encryptPwd);
      return observableFieldLoginModelObservableField.get().encryptPwd = encryptPwd;
  }

}

4.修改xml文件,并修改Activity引入ViewModel

<data>

      <variable
          name="observableFieldViewModel"
          type="com.example.mvvmgithub.viewmodel.ObservableFieldViewModel" />
  </data>

//双向绑定将@{}改为@={}
android:text="@={observableFieldViewModel.nickName}"
android:text="@={observableFieldViewModel.password}"

Activity引入ViewModel

      activityPsdLoginBinding = DataBindingUtil.setContentView(this, R.layout.activity_observable_field);
      observableFieldViewModel = new ObservableFieldViewModel();
      activityPsdLoginBinding.setObservableFieldViewModel(observableFieldViewModel);

Demo源码

github项目地址: https://github.com/zcyyouminghuo/mvvmRetrofit

CSDN资源地址:https://download.csdn.net/download/qq_42625299/13022662

猜你喜欢

转载自blog.csdn.net/qq_42625299/article/details/109235332