Не удается правильно получить мои данные с помощью ViewModelProviders? - PullRequest
1 голос
/ 11 апреля 2020

Я пытаюсь использовать MVVM, я пытаюсь получить данные в моем Viewodel (обычно поступающем из службы) и установить их для своей деятельности, но кажется, что это не работает, когда я пытаюсь просто простой ArrayList ContractModel и добавьте его в мои адаптеры, все работает нормально, но когда я пытаюсь вызвать мои 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);

    }
}

Это мой ViewModel:

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());
        }

    }
}

Любая помощь будет высоко ценится.

Ответы [ 2 ]

1 голос
/ 11 апреля 2020

Быстрое исправление

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

1 голос
/ 11 апреля 2020

Я думаю, что проблема в вашем коде в том, что ссылка на список снова и снова меняется, когда ответ приходит и передается адаптеру, хотя вы не опубликовали код своего адаптера, но я могу предположить, что вы перезаписываете ссылку на список в адаптере, что вы должны делать Сохранять ArrayList в адаптере с момента его запуска, когда вы передаете новый список адаптеру, добавляете элементы в существующий список и вызываете notifyDataSetChanged (), чтобы у адаптера была старая ссылка на список и обновит sh новых предметов в представлении переработчика. Представительский код

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)
}

}

И еще одна вещь, которую я заметил, вы не наблюдаете изменений в liveata, поэтому очевидно, что в следующий раз, когда вы получите контракт, вы не получите никакой триггерной точки, когда чтобы обновить sh ваш адаптер с помощью notifyDataSetChanged.

Так что в своей деятельности напишите что-то вроде этого. Я пишу псевдокод для понимания.

contractsListViewModel.contractList.observe{
adapter.updateList(newList);
adapter.notifydataSetCHanged()
}
...