单击按钮时的Android ViewModel LiveData更新视图

Pra*_*ina 2 android mvvm android-architecture-components

我正在学习本教程以学习ViewModel和LiveData.在我的情况下,我只是在按钮点击时生成随机字符串并尝试更新文本视图,而不是从网络获取数据.问题是当按钮单击更改数据时,textview不会更新,但只有在切换方向时才会更新.

活动类(扩展LifecycleActivity)

public class PScreen extends BaseActivity {
  @Override protected void onCreate(@Nullable Bundle savedInstanceState) {

super.onCreate(savedInstanceState);
setContentView(R.layout.places_screen);

final UserModel viewModel = ViewModelProviders.of(this).get(UserModel.class);
viewModel.init();

viewModel.getUser().observe(this, new Observer<User>() {
  @Override public void onChanged(@Nullable User user) {
    ((TextView) findViewById(R.id.name)).setText(user.getName());
  }
});

findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
  @Override public void onClick(View v) {
    final MutableLiveData<User> data = new MutableLiveData<>();
    User user = new User();
    user.setName(String.valueOf(Math.random() * 1000));
    data.postValue(user);
    viewModel.setUser(data); // Why it does not call observe()
  }
});
  }
}
Run Code Online (Sandbox Code Playgroud)

ViewModel类

package timsina.prabin.tripoptimizer.model;

import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.ViewModel;

public class UserModel extends ViewModel {
  private LiveData<User> user;

  public void init() {
    if (this.getUser() != null) {
      return;
    }
    this.user = new LiveData<User>() {
      @Override protected void setValue(User value) {
        value.setName("Fresh New Name");
        super.setValue(value);
      }
    };
  }

  public LiveData<User> getUser() {
    return user;
  }

  public void setUser(LiveData<User> user) {
    this.user = user;
  }
}
Run Code Online (Sandbox Code Playgroud)

niq*_*eco 6

您每次都在创建一个新的LiveData实例!你不应该这样做.如果你这样做,所有以前的观察者将被忽略.

在这种情况下,您可以将setUSer(LiveData<User>)ViewModel上的方法替换为setUser(User u)(使用User而不是LiveData),然后user.setValue(u)在其中进行操作.

当然,必须在ViewModel类中初始化LiveData成员,如下所示:

final private LiveData<User> user = new MutableLiveData<>();
Run Code Online (Sandbox Code Playgroud)

它会工作,因为它会通知现有的观察员.