Мне нужна помощь с обновлением элемента в RecyclerView, в котором данные предоставляются путем наблюдения LiveData.
Каждый элемент в RecyclerView представлен как простой класс данных "ComputerItem ». У меня есть ViewModel, которая предоставляет данные из API от Retrofit. Я наблюдаю данные во Fragment, а затем обновляю адаптер - как мы всегда делаем.
Но теперь у меня будет кнопка Check
во Fragment, которая для каждой записи должна вызывать другую функцию во ViewModel checkComputer(int computerId)
, получать статус из API, обновить Status
поле в классе ComputerItem и, конечно, обновить элемент в RecyclerView.
Как его достичь ??
Компьютер. java
class ComputerItem {
enum Status { UNKNOWN, ONLINE, OFFLINE, QUERYING }
public int id;
public String name;
public Status status;
}
ComputerListViewModel. java
class ComputerListViewModel extends ViewModel {
private ApiService apiService;
private MutableLiveData<List<ComputerItem>> computerList = new MutableLiveData<>();
private CompositeDisposable disposables = new CompositeDisposable();
public ComputerListViewModel(ApiService apiservice) {
this.apiService = apiservice;
}
public LiveData<List<ComputerItem>> observerComputerList() {
return computerList;
}
public void fetchComputerList() {
disposables.add(
apiService.readComputerList()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(computerList -> {
computerList.setValue(computerList);
})
);
}
public void checkComputer(int computerId) {
disposables.add(
apiService.checkComputer(computerId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(response -> { //????
})
);
}
}
ComputersListAdapter. java
public class ComputersListAdapter extends RecyclerView.Adapter<ComputersListAdapter.ComputerViewHolder> {
private List<ComputerItem> computerItems;
public ComputersListAdapter() {
computerItems = new ArrayList<>();
}
public void setComputerItems(List<ComputerItem> data) {
computerItems = data;
notifyDataSetChanged();
}
@NonNull
@Override
public ComputerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_computer, parent);
return new ComputerViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ComputerViewHolder holder, int position) {
holder.bind(computerItems.get(position));
}
@Override
public int getItemCount() {
return computerItems.size();
}
public class ComputerViewHolder extends RecyclerView.ViewHolder {
private TextView name;
private TextView status;
public ComputerViewHolder(@NonNull View itemView) {
super(itemView);
name = itemView.findViewById(R.id.name);
status = itemView.findViewById(R.id.status);
}
public void bind(ComputerItem computerItem) {
name.setText(computerItem.name);
status.setText(computerItem.status);
}
}
}
КомпьютерыФрагмент. java
public class ComputersFragment extends BaseFragment {
// rest of standard code
//....
private void subscribeObservers() {
computersVM.observerComputerItems().removeObservers(getViewLifecycleOwner());
computersVM.observerComputerItems().observe(getViewLifecycleOwner(), computersList -> {
computersAdapter.setComputerItems(computersList);
break;
}
});
}
}