Skip to content
Advertisement

Update recycler view when a item is deleted on onBindViewHolder listener

I’m having a problem, that maybe we can solve it and help the community. I have made an Adapter for my RecyclerView and I have created a listener for the constraint layout in order to remove one element of the list. As you can see in the code the delete message works well but I don’t know how to update the RecyclerView from the AccountFragment (the one that’s using this adapter). Does anyone know how to notify that changes?

AccountFragment:

    public class AccountFragment extends Fragment {

    private TextView textViewUserProfileUsername;
    private TextView textViewUserProfileDescription;
    private ImageButton imageButtonAccountEdit;
    private EditText editTextAccountDescription;
    private RecyclerView recyclerViewUserProfileComments;
    private TextView textViewUserProfileNoComments;
    private ImageView imageViewUserProfileSendMessage;
    private EditText editTextUserProfileSendMessage;
    private final Gson gson = new Gson();
    private User userLocal;
    private SharedPreferences sharedPreferences;
    private Context context;
    private AlertDialog dialog;
    private String previousDescription;
    private AccountCommentsAdapter accountCommentsAdapter;
    private final List<UserComments> userCommentsList = new ArrayList<>();

    public AccountFragment() {
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        context = getActivity();
        assert context != null;
        sharedPreferences = context.getSharedPreferences(Constants.sharedPreferencesDocName, Context.MODE_PRIVATE);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_account, container, false);
    }

    @Override
    public void onViewCreated(@NonNull @NotNull View view, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        bindUI(view);
        setListeners();
        userLocal = gson.fromJson(sharedPreferences.getString("user", ""), User.class);
        showUserInformation();
        setAdapter();
    }

    private void bindUI(View view) {
        textViewUserProfileUsername = view.findViewById(R.id.textViewUserProfileUsername);
        textViewUserProfileDescription = view.findViewById(R.id.textViewUserProfileDescription);
        imageButtonAccountEdit = view.findViewById(R.id.imageButtonAccountEdit);
        recyclerViewUserProfileComments = view.findViewById(R.id.recyclerViewUserProfileComments);
        textViewUserProfileNoComments = view.findViewById(R.id.textViewUserProfileNoComments);
        imageViewUserProfileSendMessage = view.findViewById(R.id.imageViewUserProfileSendMessage);
        editTextUserProfileSendMessage = view.findViewById(R.id.editTextUserProfileSendMessage);
    }

    private void setListeners() {
        imageButtonAccountEdit.setOnClickListener(v -> showEditDescriptionDialog());
        imageViewUserProfileSendMessage.setOnClickListener(view -> {
            if (!TextUtils.isEmpty(editTextUserProfileSendMessage.getText().toString())) {
                final Date currentTime = new Date();
                @SuppressLint("SimpleDateFormat") SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm");
                TimeZone timeZone = simpleDateFormat.getTimeZone();
                simpleDateFormat.setTimeZone(timeZone);
                String date = simpleDateFormat.format(currentTime);
                final UserComments userCommentsToAdd = new UserComments(userLocal.getId(), userLocal.getId(), userLocal.getUsername(), userLocal.getUsername(), editTextUserProfileSendMessage.getText().toString().trim(), date);
                editTextUserProfileSendMessage.setText("");
                addComment(userCommentsToAdd);
            }
        });
    }

    private void showUserInformation() {
        textViewUserProfileUsername.setText(userLocal.getUsername());
        textViewUserProfileDescription.setText(userLocal.getDescription());
        getUserComments();
    }

    private void showEditDescriptionDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setTitle(getString(R.string.edit_description));
        final View customLayout = getLayoutInflater().inflate(R.layout.alert_dialog_edit_account, null);
        builder.setView(customLayout);
        dialog = builder.create();
        editTextAccountDescription = customLayout.findViewById(R.id.editTextAccountDescription);
        if (userLocal.getDescription() != null) {
            editTextAccountDescription.setText(userLocal.getDescription());
            previousDescription = editTextAccountDescription.getText().toString();
        }
        Button buttonAccountCancelDescription = customLayout.findViewById(R.id.buttonAccountCancelDescription);
        Button buttonAccountSaveDescription = customLayout.findViewById(R.id.buttonAccountSaveDescription);
        buttonAccountSaveDescription.setOnClickListener(v -> saveUserDescription());
        buttonAccountSaveDescription.setOnClickListener(v -> {
            if (editTextAccountDescription.getText().toString().length() <= 150) {
                saveUserDescription();
            } else {
                setErrors(2);
            }
        });
        editTextAccountDescription.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                if (s.length() > 150) {
                    setErrors(2);
                }
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });
        buttonAccountCancelDescription.setOnClickListener(v -> dialog.dismiss());
        dialog.setCancelable(false);
        dialog.show();
    }

    private void saveUserDescription() {
        if (!editTextAccountDescription.getText().toString().isEmpty()) {
            if (!editTextAccountDescription.getText().toString().equals(previousDescription)) {
                userLocal.setDescription(editTextAccountDescription.getText().toString());
                sharedPreferences.edit().putString("user", gson.toJson(userLocal)).apply();
                Thread thread = new Thread() {
                    @Override
                    public void run() {
                        Response response;
                        try {
                            response = UserRequests.editUserDescription(userLocal.getId(), userLocal.getDescription());
                            if (response.code() == 200) {
                                String responseBody = Objects.requireNonNull(response.body()).string();
                                responseBody = responseBody.replace("rn", "");
                                if (responseBody.contains("1")) {
                                    updateDescription();
                                } else if (responseBody.contains("2")) {
                                    updateDescription();
                                } else {
                                    setErrors(1);
                                }
                            } else {
                                setErrors(1);
                            }
                        } catch (Exception ex) {
                            ex.printStackTrace();
                        }
                    }
                };
                thread.start();
            } else {
                setErrors(4);
            }

        } else {
            setErrors(3);
        }
    }

    private void updateDescription() {
        Thread thread = new Thread() {
            public void run() {
                requireActivity().runOnUiThread(() -> {
                    textViewUserProfileDescription.setText(userLocal.getDescription());
                    dialog.dismiss();
                });
            }
        };
        thread.start();
    }

    private void setErrors(int error) {
        switch (error) {
            case 1:
                Thread thread = new Thread() {
                    public void run() {
                        requireActivity().runOnUiThread(() -> Toast.makeText(context, getString(R.string.generic_error), Toast.LENGTH_SHORT).show());
                    }
                };
                thread.start();
                break;
            case 2:
                editTextAccountDescription.setError(getString(R.string.description_length));
                editTextAccountDescription.requestFocus();
                break;
            case 3:
                editTextAccountDescription.setError(getString(R.string.required_field));
                editTextAccountDescription.requestFocus();
                break;
            case 4:
                dialog.dismiss();
                break;
        }
    }

    private void setAdapter() {
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context);
        linearLayoutManager.setStackFromEnd(true);
        recyclerViewUserProfileComments.setLayoutManager(linearLayoutManager);
        recyclerViewUserProfileComments.scrollToPosition(userCommentsList.size() - 1);
    }

    private void displayMessages() {
        if (userCommentsList.size() > 0) {
            Thread thread = new Thread() {
                public void run() {
                    requireActivity().runOnUiThread(() -> {
                        if (recyclerViewUserProfileComments.getVisibility() == View.GONE) {
                            recyclerViewUserProfileComments.setVisibility(View.VISIBLE);
                        }
                        if (textViewUserProfileNoComments.getVisibility() == View.VISIBLE) {
                            textViewUserProfileNoComments.setVisibility(View.GONE);
                        }
                        accountCommentsAdapter = new AccountCommentsAdapter(context, userCommentsList);
                        recyclerViewUserProfileComments.setAdapter(accountCommentsAdapter);
                        recyclerViewUserProfileComments.scrollToPosition(userCommentsList.size() - 1);
                        accountCommentsAdapter.notifyDataSetChanged();
                    });
                }
            };
            thread.start();
        } else {
            Thread thread = new Thread() {
                public void run() {
                    requireActivity().runOnUiThread(() -> {
                        recyclerViewUserProfileComments.setVisibility(View.GONE);
                        textViewUserProfileNoComments.setVisibility(View.VISIBLE);
                    });
                }
            };
            thread.start();
        }
    }

    private void addComment(UserComments userCommentsToAdd) {
        Thread thread = new Thread() {
            @Override
            public void run() {
                Response response;
                try {
                    response = UserCommentsRequests.addUserComment(userCommentsToAdd);
                    if (response.code() == 200) {
                        String responseBody = Objects.requireNonNull(response.body()).string();
                        responseBody = responseBody.replace("rn", "");
                        if (responseBody.contains("1")) {
                            userCommentsList.add(userCommentsToAdd);
                            userCommentsList.clear();
                            getUserComments();
                        }
                    } else if (response.code() == 204) {
                        displayMessages();
                    } else {
                        setErrors(1);
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        };
        thread.start();
    }

    private void getUserComments() {
        Thread thread = new Thread() {
            @Override
            public void run() {
                Response response;
                try {
                    response = UserCommentsRequests.getUserComments(userLocal.getId());
                    if (response.code() == 200) {
                        String responseBody = Objects.requireNonNull(response.body()).string();
                        responseBody = responseBody.replace("rn", "");
                        JSONArray responseArray = new JSONArray(responseBody);
                        for (int i = 0; i < responseArray.length(); i++) {
                            String jsonObjectString = responseArray.getJSONObject(i).toString();
                            userCommentsList.add(gson.fromJson(jsonObjectString, UserComments.class));
                        }
                        displayMessages();
                    } else if (response.code() == 204) {
                        displayMessages();
                    } else {
                        setErrors(1);
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        };
        thread.start();
    }
}

AccountCommentsAdapter:

    public class AccountCommentsAdapter extends RecyclerView.Adapter<AccountCommentsAdapter.AccountCommentsAdapterViewHolder> {

    private final Context context;
    List<UserComments> userCommentsList;
    public static final int MSG_TYPE_LEFT = 0;
    public static final int MSG_TYPE_RIGHT = 1;

    public AccountCommentsAdapter(Context context, List<UserComments> userCommentsList) {
        this.context = context;
        this.userCommentsList = userCommentsList;
    }

    @NonNull
    @NotNull
    @Override
    public AccountCommentsAdapterViewHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) {
        View view;
        if (viewType == MSG_TYPE_RIGHT) {
            view = LayoutInflater.from(context).inflate(R.layout.fragment_chat_message_sent, parent, false);
        } else {
            view = LayoutInflater.from(context).inflate(R.layout.fragment_chat_message_received, parent, false);
        }
        return new AccountCommentsAdapterViewHolder(view);
    }

    @Override
    public int getItemViewType(int position) {
        FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
        assert firebaseUser != null;
        if (userCommentsList.get(position).getUser_from_username().equals(firebaseUser.getDisplayName())) {
            return MSG_TYPE_RIGHT;
        } else {
            return MSG_TYPE_LEFT;
        }
    }

    @Override
    public void onBindViewHolder(@NonNull @NotNull AccountCommentsAdapterViewHolder holder, int position) {
        UserComments userComments = userCommentsList.get(position);
        int viewType = holder.getItemViewType();
        if (viewType == MSG_TYPE_LEFT) {
            holder.textViewMessageUsername.setText(userComments.getUser_from_username());
            holder.textViewMessageUsername.setOnClickListener(v -> {
                Intent intent = new Intent(context, UserProfileActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                Bundle bundle = new Bundle();
                bundle.putString("userId", userComments.getUser_from_id());
                bundle.putString("username", userComments.getUser_from_username());
                intent.putExtras(bundle);
                context.startActivity(intent);
            });
            holder.constraintLayoutMessageRight.setOnLongClickListener(v -> {
                AlertDialog.Builder builder = new AlertDialog.Builder(context);
                builder.setMessage(R.string.delete_message)
                        .setPositiveButton(R.string.yes, (dialogInterface, i) -> deleteMessage(position))
                        .setNegativeButton(R.string.no, (dialogInterface, which) -> dialogInterface.dismiss());
                builder.create();
                builder.show();
                return false;
            });
        } else {
            holder.constraintLayoutMessageRight.setOnLongClickListener(v -> {
                AlertDialog.Builder builder = new AlertDialog.Builder(context);
                builder.setMessage(R.string.delete_message)
                        .setPositiveButton(R.string.yes, (dialogInterface, i) -> deleteMessage(position))
                        .setNegativeButton(R.string.no, (dialogInterface, which) -> dialogInterface.dismiss());
                builder.create();
                builder.show();
                return false;
            });
        }
        holder.textViewMessageMessage.setText(userComments.getMessage());
        holder.textViewMessageTime.setText(userComments.getCreated_time());
    }

    @Override
    public int getItemCount() {
        return userCommentsList.size();
    }

    public static class AccountCommentsAdapterViewHolder extends RecyclerView.ViewHolder {
        ConstraintLayout constraintLayoutMessageRight;
        TextView textViewMessageMessage;
        TextView textViewMessageTime;
        TextView textViewMessageUsername;


        public AccountCommentsAdapterViewHolder(@NonNull @NotNull View itemView) {
            super(itemView);
            textViewMessageMessage = itemView.findViewById(R.id.textViewMessageMessage);
            textViewMessageTime = itemView.findViewById(R.id.textViewMessageTime);
            constraintLayoutMessageRight = itemView.findViewById(R.id.constraintLayoutMessageRight);
            textViewMessageUsername = itemView.findViewById(R.id.textViewMessageUsername);
        }
    }

    private void deleteMessage(int position) {
        UserComments userCommentsToRemove = userCommentsList.get(position);
        Thread thread = new Thread() {
            @Override
            public void run() {
                Response response;
                try {
                    response = UserCommentsRequests.removeUserComments(userCommentsToRemove.getId());
                    if (response.code() == 200) {
                        String responseBody = Objects.requireNonNull(response.body()).string();
                        responseBody = responseBody.replace("rn", "");
                        if (responseBody.contains("1")) {
                            userCommentsList.remove(position);
                        // Here it should update the recyclerview in order to notify that element has been removed.
                        }
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        };
        thread.start();
    }
}

UPDATE:

Solved by adding this method and then call it after userCommentsList.remove(position):

private void updateUI(){
    Handler mainHandler = new Handler(context.getMainLooper());
    Runnable runnable = this::notifyDataSetChanged;
    mainHandler.post(runnable);
}

Advertisement

Answer

Inside the adapter you can use notifyDataSetChanged()

User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement