使用 ViewModelProviders 无法正确获取我的数据?
Not getting my data correctly using ViewModelProviders?
我正在尝试使用 MVVM,我正在尝试获取我的 Viewodel 中的数据(通常来自服务)并将它们设置到我的 activity,但它似乎不起作用,当我只尝试了一个简单的 ContractModel ArrayList 并将其添加到我的适配器中,一切正常,但是当我尝试调用我的 ViewModel 时,一切都停止了。
我正在学习一门与我做同样事情但结果不同的课程。
这是我的 MainActivity:
public class MainActivity extends AppCompatActivity {
ContractsListViewModel contractsListViewModel;
@BindView(R.id.contractList)
RecyclerView contractList;
RecyclerView.Adapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
contractList.setLayoutManager(new LinearLayoutManager(this));
contractsListViewModel = ViewModelProviders.of(this).get(ContractsListViewModel.class);
contractsListViewModel.call();
adapter = new ContractListAdapter(this, contractsListViewModel.contractList.getValue());
contractList.setAdapter(adapter);
}
}
那是我的视图模型:
public class ContractsListViewModel extends ViewModel {
public MutableLiveData<List<ContractModel>> contractList;
MutableLiveData<Boolean> isLoading;
MutableLiveData<Boolean> error;
public void call(){
fetchContracts();
}
public void fetchContracts(){
ContractModel contractModel = new ContractModel(1, "hfdfd", "h");
ContractModel contractModel1 = new ContractModel(1, "hfdffddd", "h");
ContractModel contractModel2 = new ContractModel(1, "hdffd", "j");
ContractModel contractModel3 = new ContractModel(1, "hdffdfd", "h");
List<ContractModel> list = new ArrayList<ContractModel>();
list.add(...allofthem);
contractList.setValue(list);
}
}
我的适配器工作正常,因为它与我上面提到的 ArrayList 一起工作。
但这里是:
public class ContractListAdapter extends RecyclerView.Adapter<ContractListAdapter.ContractViewHolder> {
List<ContractModel> contracts;
Context context;
public ContractListAdapter(Context context, List<ContractModel> contracts){
this.context = context;
this.contracts = contracts;
}
@NonNull
@Override
public ContractViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.contrat, parent, false);
return new ContractViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ContractViewHolder holder, int position) {
holder.bind(contracts.get(position));
}
@Override
public int getItemCount() {
return this.contracts.size();
}
public class ContractViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.courtier)
TextView courtier;
public ContractViewHolder(@NonNull View view){
super(view);
ButterKnife.bind(this, view);
}
public void bind(ContractModel contractModel){
courtier.setText(contractModel.getCourtier());
}
}
}
如有任何帮助,我们将不胜感激。
我认为你的代码中的问题是当响应到来并传递给适配器时,列表的引用一次又一次地改变,虽然你没有发布你的适配器的代码,但我可以假设你正在覆盖适配器中的列表引用,你应该做什么 自启动以来在适配器中保留一个 ArrayList,当你将新列表传递给适配器时,在现有列表中添加项目并调用 notifyDataSetChanged(),因此适配器将具有旧引用列出并将刷新回收站视图中的新项目。
代表代码
Class MyAdapter extends RecycelerviewAdapter{
private List<ContractModel> globalList = new ArrayList();
public ( List<ContractModel> newlist){
globalList.addAll(newlist)
}
public updateList(List<ContractModel> newlist){
globalList.addAll(newlist)
}
}
我还注意到一件事,你没有观察到 livedata 的变化,所以很明显下次你获取合同时,你不会得到任何触发点,什么时候用 notifyDataSetChanged 刷新你的适配器。
所以在你的 activity 中写下这样的东西。我正在编写伪代码以供理解。
contractsListViewModel.contractList.observe{
adapter.updateList(newList);
adapter.notifydataSetCHanged()
}
快速修复
public MutableLiveData<List<ContractModel>> contractList=new MutableLiveData<>();
因为您应该先创建一个列表,然后再在此处设置数据 contractList.setValue(list);
更结构化的解决方案
public class ContractsListViewModel extends ViewModel {
public MutableLiveData<List<ContractModel>> contractList=new MutableLiveData<>();
MutableLiveData<Boolean> isLoading;
MutableLiveData<Boolean> error;
public void call(){
fetchContracts();
}
public void fetchContracts(){
ContractModel contractModel = new ContractModel(1, "hfdfd", "h");
ContractModel contractModel1 = new ContractModel(1, "hfdffddd", "h");
ContractModel contractModel2 = new ContractModel(1, "hdffd", "j");
ContractModel contractModel3 = new ContractModel(1, "hdffdfd", "h");
List<ContractModel> list = new ArrayList<ContractModel>();
list.add(contractModel);
list.add(contractModel1);
list.add(contractModel2);
list.add(contractModel3);
contractList.postValue(list);
}
}
MainActivity onCreate()
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
contractList.setLayoutManager(new LinearLayoutManager(this));
contractsListViewModel = ViewModelProviders.of(this).get(ContractsListViewModel.class);
contractsListViewModel.call();
contractsListViewModel.contractList.observe(this,contractModels -> {
adapter = new ContractListAdapter(MainActivity.this, contractModels);
contractList.setAdapter(adapter);
});
}
检查 了解 setValue 和 postValue 之间的区别
我正在尝试使用 MVVM,我正在尝试获取我的 Viewodel 中的数据(通常来自服务)并将它们设置到我的 activity,但它似乎不起作用,当我只尝试了一个简单的 ContractModel ArrayList 并将其添加到我的适配器中,一切正常,但是当我尝试调用我的 ViewModel 时,一切都停止了。
我正在学习一门与我做同样事情但结果不同的课程。
这是我的 MainActivity:
public class MainActivity extends AppCompatActivity {
ContractsListViewModel contractsListViewModel;
@BindView(R.id.contractList)
RecyclerView contractList;
RecyclerView.Adapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
contractList.setLayoutManager(new LinearLayoutManager(this));
contractsListViewModel = ViewModelProviders.of(this).get(ContractsListViewModel.class);
contractsListViewModel.call();
adapter = new ContractListAdapter(this, contractsListViewModel.contractList.getValue());
contractList.setAdapter(adapter);
}
}
那是我的视图模型:
public class ContractsListViewModel extends ViewModel {
public MutableLiveData<List<ContractModel>> contractList;
MutableLiveData<Boolean> isLoading;
MutableLiveData<Boolean> error;
public void call(){
fetchContracts();
}
public void fetchContracts(){
ContractModel contractModel = new ContractModel(1, "hfdfd", "h");
ContractModel contractModel1 = new ContractModel(1, "hfdffddd", "h");
ContractModel contractModel2 = new ContractModel(1, "hdffd", "j");
ContractModel contractModel3 = new ContractModel(1, "hdffdfd", "h");
List<ContractModel> list = new ArrayList<ContractModel>();
list.add(...allofthem);
contractList.setValue(list);
}
}
我的适配器工作正常,因为它与我上面提到的 ArrayList 一起工作。 但这里是:
public class ContractListAdapter extends RecyclerView.Adapter<ContractListAdapter.ContractViewHolder> {
List<ContractModel> contracts;
Context context;
public ContractListAdapter(Context context, List<ContractModel> contracts){
this.context = context;
this.contracts = contracts;
}
@NonNull
@Override
public ContractViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.contrat, parent, false);
return new ContractViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ContractViewHolder holder, int position) {
holder.bind(contracts.get(position));
}
@Override
public int getItemCount() {
return this.contracts.size();
}
public class ContractViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.courtier)
TextView courtier;
public ContractViewHolder(@NonNull View view){
super(view);
ButterKnife.bind(this, view);
}
public void bind(ContractModel contractModel){
courtier.setText(contractModel.getCourtier());
}
}
}
如有任何帮助,我们将不胜感激。
我认为你的代码中的问题是当响应到来并传递给适配器时,列表的引用一次又一次地改变,虽然你没有发布你的适配器的代码,但我可以假设你正在覆盖适配器中的列表引用,你应该做什么 自启动以来在适配器中保留一个 ArrayList,当你将新列表传递给适配器时,在现有列表中添加项目并调用 notifyDataSetChanged(),因此适配器将具有旧引用列出并将刷新回收站视图中的新项目。 代表代码
Class MyAdapter extends RecycelerviewAdapter{
private List<ContractModel> globalList = new ArrayList();
public ( List<ContractModel> newlist){
globalList.addAll(newlist)
}
public updateList(List<ContractModel> newlist){
globalList.addAll(newlist)
}
}
我还注意到一件事,你没有观察到 livedata 的变化,所以很明显下次你获取合同时,你不会得到任何触发点,什么时候用 notifyDataSetChanged 刷新你的适配器。
所以在你的 activity 中写下这样的东西。我正在编写伪代码以供理解。
contractsListViewModel.contractList.observe{
adapter.updateList(newList);
adapter.notifydataSetCHanged()
}
快速修复
public MutableLiveData<List<ContractModel>> contractList=new MutableLiveData<>();
因为您应该先创建一个列表,然后再在此处设置数据 contractList.setValue(list);
更结构化的解决方案
public class ContractsListViewModel extends ViewModel {
public MutableLiveData<List<ContractModel>> contractList=new MutableLiveData<>();
MutableLiveData<Boolean> isLoading;
MutableLiveData<Boolean> error;
public void call(){
fetchContracts();
}
public void fetchContracts(){
ContractModel contractModel = new ContractModel(1, "hfdfd", "h");
ContractModel contractModel1 = new ContractModel(1, "hfdffddd", "h");
ContractModel contractModel2 = new ContractModel(1, "hdffd", "j");
ContractModel contractModel3 = new ContractModel(1, "hdffdfd", "h");
List<ContractModel> list = new ArrayList<ContractModel>();
list.add(contractModel);
list.add(contractModel1);
list.add(contractModel2);
list.add(contractModel3);
contractList.postValue(list);
}
}
MainActivity onCreate()
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
contractList.setLayoutManager(new LinearLayoutManager(this));
contractsListViewModel = ViewModelProviders.of(this).get(ContractsListViewModel.class);
contractsListViewModel.call();
contractsListViewModel.contractList.observe(this,contractModels -> {
adapter = new ContractListAdapter(MainActivity.this, contractModels);
contractList.setAdapter(adapter);
});
}
检查