I have a list adapter connected to a recycler view. I use SwipToDelete which calls deleteItem()
.
If I remove an item, the list entry in the recycler view gets removed.
The problem: If there is only one item in the recycler view and I try to remove it, the list entry is still visible in the recycler view. But it is gone as soon as a restart the app.
I think notifyItemRemoved()
should take care of it, like it does if there is more than one item.
RepoListAdapter:
public class RepoListAdapter extends ListAdapter<Repo, RepoViewHolder> {
private RecyclerView recyclerView;
public RepoListAdapter(@NonNull DiffUtil.ItemCallback<Repo> diffCallback) {
super(diffCallback);
}
@NonNull @Override
public RepoViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
return RepoViewHolder.create(viewGroup);
}
@Override
public void onBindViewHolder(RepoViewHolder holder, int position) {
Repo current = getItem(position);
holder.bind(current.getName());
}
public static class RepoDiff extends DiffUtil.ItemCallback<Repo> {
@Override
public boolean areItemsTheSame(@NonNull Repo oldItem, @NonNull Repo newItem) {
return oldItem == newItem;
}
@Override
public boolean areContentsTheSame(@NonNull Repo oldItem, @NonNull Repo newItem) {
return oldItem.getName().equals(newItem.getName());
}
}
@Override
public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
this.recyclerView = recyclerView;
}
public Context getContext() {
return recyclerView.getContext();
}
public void deleteItem(int position) {
Repo recentlyDeletedRepo = getItem(position);
RepoViewModel repoViewModel = new ViewModelProvider((ViewModelStoreOwner) getContext()).get(RepoViewModel.class);
repoViewModel.delete(recentlyDeletedRepo);
notifyItemRemoved(position);
notifyItemRangeRemoved(position, 1);
Snackbar snackbar = Snackbar.make(recyclerView, R.string.snackbar_undo, Snackbar.LENGTH_LONG);
snackbar.setAction(R.string.snackbar_undo, v -> undoDelete(recentlyDeletedRepo, position));
snackbar.show();
}
private void undoDelete(Repo recentlyDeletedRepo, int position) {
RepoViewModel repoViewModel = new ViewModelProvider((ViewModelStoreOwner) getContext()).get(RepoViewModel.class);
repoViewModel.insert(recentlyDeletedRepo);
notifyItemInserted(position);
}
}
RepoViewModel:
public class RepoViewModel extends AndroidViewModel {
private final RepoRepository repoRepository;
private final LiveData<List<Repo>> allRepos;
private Repo currentRepo;
public RepoViewModel(Application application) {
super(application);
repoRepository = new RepoRepository(application);
allRepos = repoRepository.getAllRepos();
}
public Repo getCurrentRepo() {
return currentRepo;
}
public void setCurrentRepo(Repo currentRepo) {
this.currentRepo = currentRepo;
}
public LiveData<Repo> getRepoById(int id) {
return repoRepository.getRepoById(id);
}
public LiveData<List<Repo>> getAllRepos() {
return allRepos;
}
public long insert(Repo repo) {
return repoRepository.insert(repo);
}
public void update(Repo repo) {
repoRepository.update(repo);
}
public void delete(Repo repo) {
repoRepository.delete(repo);
}
}
ProjectsFragment:
public class ProjectsFragment extends Fragment {
private RecyclerView recyclerView;
private TextView textview_no_project;
private RepoListAdapter repoListAdapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
FloatingActionButton floatingActionButton = ((MainActivity) requireActivity()).getFloatingActionButton();
floatingActionButton.setVisibility(View.VISIBLE);
return inflater.inflate(R.layout.fragment_projects, container, false);
}
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
textview_no_project = view.findViewById(R.id.textview_no_project);
repoListAdapter = new RepoListAdapter(new RepoListAdapter.RepoDiff());
recyclerView = view.findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(requireActivity()));
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), DividerItemDecoration.VERTICAL);
recyclerView.addItemDecoration(dividerItemDecoration);
recyclerView.setAdapter(repoListAdapter);
ItemTouchHelper itemTouchHelper = new
ItemTouchHelper(new SwipeToDeleteCallback(repoListAdapter));
itemTouchHelper.attachToRecyclerView(recyclerView);
RepoViewModel repoViewModel = new ViewModelProvider(requireActivity()).get(RepoViewModel.class);
repoViewModel.getAllRepos().observe(getViewLifecycleOwner(), this::onLoaded);
}
private void onLoaded(List<Repo> list){
if (list.size() == 0) {
textview_no_project.setVisibility(View.VISIBLE);
}
else {
textview_no_project.setVisibility(View.INVISIBLE);
repoListAdapter.submitList(list);
}
}
}
question from:
https://stackoverflow.com/questions/65887266/recylerview-does-not-remove-last-item 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…