2

我正在按照本教程学习 ViewModel 和 LiveData。就我而言,我不是从网络获取数据,而是在按钮单击时生成随机字符串并尝试更新文本视图。问题是当通过按钮单击更改数据时文本视图不会更新,但仅在切换方向时才会更新。

Activity 类(扩展 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()
  }
});
  }
}

视图模型类

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;
  }
}
4

4 回答 4

6

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

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

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

final private LiveData<User> user = new MutableLiveData<>();

然后它将起作用,因为它将通知现有的观察者。

于 2017-05-24T19:55:19.970 回答
3

我能够通过使用 MutableLiveData 而不是 LiveData 以某种方式解决这个问题。 模型类

private MutableLiveData<User> user2;
  public void init() {
    if (user2 == null) {
      user2 = new MutableLiveData<>();
    }
}

  public MutableLiveData<User> getUser2() {
    return user2;
  }

  public void setUser2(final User user) {
    user2.postValue(user);
  }

活动

 viewModel.getUser2().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) {
       User user = new User();
        viewModel.getUser().postValue(user);
        }
    });
于 2017-05-24T14:47:49.797 回答
0

您替换对 UserModel 中对象的引用,尝试交换代码行

data.postValue(user);
viewModel.setUser(data); // Why it does not call observe()

更换

viewModel.setUser(data); // Why it does not call observe()
data.postValue(user);
于 2017-05-24T11:38:06.833 回答
0

尝试像@niqueco 提到的那样修改您的代码,在方法中设置您更新的方法,setUser()并在活动中更改您的onclick()侦听器以仅发送新的用户数据信息。LiveData 将帮助您的其他工作。

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.setValue(user); //the live data will help u push data
  }
}

活动课

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(user); // Why it does not call observe() 
  }
});
  }
}
于 2017-06-20T15:18:35.997 回答