RecyclerView 颜色变化删除错误

huangapple go评论69阅读模式
英文:

RecyclerView Color Change Deletion Bug

问题

分配任务-删除前

删除后

我正在创建一个学校计划应用程序,以便将从房间数据库中读取的作业显示在RecyclerView中。每个项目行都有作业名称、类型和截止日期,以及一个删除按钮。每个项目行的背景在作业过期时变为红色,在作业今天到期时变为绿色,在将来到期时(今天之后)保持默认颜色。我遇到的问题是,当一个具有颜色(红色或绿色)的作业位于具有不同颜色的作业之上时,删除具有颜色的作业时,下面的作业会更改为先前已删除作业的颜色。如果重新启动应用程序或启动另一个活动,然后再次拉起RecyclerView,作业将恢复到其正确的颜色。

[更新] 不知道这是否会影响问题,但我用于RecyclerView的item_row.xml文件未使用CardView

这是我更改颜色的方法:

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        // 从数据库列表中获取当前位置处的数据库表
        AssignmentTable assignmentTable = assignmentList.get(position);
        // 实例化视图
        String due = "截止日期:" + assignmentTable.dueDate;
        String type = assignmentTable.type;
        holder.txtItemName.setText(assignmentTable.name);
        holder.txtItemDate.setText(due);
        holder.txtItemType.setText(type);
        // 将复选框设置为其保存的状态
        if(assignmentTable.isCompleted == true){
            holder.checkBox.setChecked(true);
        }else {
            holder.checkBox.setChecked(false);
        }
        // 获取当前截止日期并解析
        Date currentDate = getCurrentDate();
        String dueDateAsString = assignmentTable.dueDate;
        Date dueDateOfCurrentAssignment = parseDate(dueDateAsString);
        // 以编程方式更改背景颜色
        if(currentDate.equals(dueDateOfCurrentAssignment)){
            holder.txtItemDate.setText("截止日期:今天"); // 更改截止日期
            holder.itemView.setBackgroundColor(Color.parseColor("#228b22")); // 更改颜色为绿色
            Log.d("已到达", "绿色");
        }
        if(dueDateOfCurrentAssignment.before(currentDate)){
            holder.itemView.setBackgroundColor(Color.parseColor("#8b0000")); // 背景变为红色
            holder.txtItemDate.setTextColor(Color.parseColor("#ff7a7a")); // 文本变为亮红色
            Log.d("已到达", "红色");
        }
        // 记录字段
        String assignment = "\n名称:" + assignmentTable.name + "\n截止日期:" + assignmentTable.dueDate 
           + "\n类型:" + assignmentTable.type + "\n已完成:" + assignmentTable.isCompleted;
        Log.d("在ONBIND结束时", "\n" + assignment);

    }

这是在删除按钮的onClick上调用的方法。

        @Override
        public void onClick(View view) {
            // 获取要删除的指定位置的数据库表
            int position = getAdapterPosition();
            AssignmentTable assignmentTable = assignmentList.get(position);
            ItemRepository itemRepository = new ItemRepository(view.getContext());
            // 从数据库中删除
            itemRepository.deleteItem(assignmentTable);
            itemRepository.updateItem(assignmentTable);
            notifyDataSetChanged();
            Toast.makeText(view.getContext(),"已删除!",Toast.LENGTH_SHORT).show();
        }
英文:

Assignments Pre-Deletion

After Deletion

I am creating a school planner app and to display the assignments I am reading from a room database into a RecyclerView. Each item row has the assignment name, type, and due date, as well as a delete button. Each item row's background turns Red if the assignment is overdue, Green if the assignment is due today, and the default color if the assignment is due in the future (past today). The bug I am running into happens when an assignment that is a color(red or green) is on top of an assignment with a different color. When the assignment that is colored is deleted, the assignment below is changed to the color of the previously deleted assignment. If the app is restarted or another activity is started and then the RecyclerView is pulled up again, the assignment is back to its correct color.

[Update] Don't know whether or not this affects the issue but my item_row.xml file for the RecyclerView does not use CardView

Here is the method where I change the color:

    @Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
//Fetching the database table at the current position from database list
AssignmentTable assignmentTable = assignmentList.get(position);
//Instantiating the views
String due = "Due: "+assignmentTable.dueDate;
String type = assignmentTable.type;
holder.txtItemName.setText(assignmentTable.name);
holder.txtItemDate.setText(due);
holder.txtItemType.setText(type);
//Setting the checkboxes to their saved state
if(assignmentTable.isCompleted == true){
holder.checkBox.setChecked(true);
}else {
holder.checkBox.setChecked(false);
}
//Fetching current due date and parsing
Date currentDate = getCurrentDate();
String dueDateAsString = assignmentTable.dueDate;
Date dueDateOfCurrentAssignment = parseDate(dueDateAsString);
//changing the background color programmatically
if(currentDate.equals(dueDateOfCurrentAssignment)){
holder.txtItemDate.setText("Due: Today"); //changes due date
holder.itemView.setBackgroundColor(Color.parseColor("#228b22")); // changes color to green
Log.d("REACHED", "GREEN COLOR");
}
if(dueDateOfCurrentAssignment.before(currentDate)){
holder.itemView.setBackgroundColor(Color.parseColor("#8b0000")); // turns the background red
holder.txtItemDate.setTextColor(Color.parseColor("#ff7a7a")); // turns text bright red
Log.d("REACHED", "RED COLOR");
}
//Logging fields
String assignment = "\nName: " + assignmentTable.name + "\nDue Date: " + assignmentTable.dueDate 
+ "\nType: " + assignmentTable.type + "\nCompleted: " + assignmentTable.isCompleted;
Log.d("AT END OF ONBIND", "\n" + assignment);
}```
and here is the method called on the delete buttons onClick. 
    @Override
public void onClick(View view) {
//Getting database table at the specified position to delete
int position = getAdapterPosition();
AssignmentTable assignmentTable = assignmentList.get(position);
ItemRepository itemRepository = new ItemRepository(view.getContext());
//Deleting from the database
itemRepository.deleteItem(assignmentTable);
itemRepository.updateItem(assignmentTable);
notifyDataSetChanged();
Toast.makeText(view.getContext(),"Deleted!",Toast.LENGTH_SHORT).show();
}```

答案1

得分: 0

在你的删除方法中调用了notifyDataSetChanged。你还应该调用notifyItemRemoved(position)

关于此事,文档中的解释如下:

通知任何已注册的观察者,数据集中先前位于 position 处的项已从数据集中删除。

希望能成功!

英文:

While you are calling notifyDataSetChanged in your delete method. You should also call notifyItemRemoved(position).

Here is what documentation says about it:

> Notify any registered observers that the item previously located at position has been removed from the data set.

Hope it works out!

答案2

得分: 0

修复了问题!原来我只需要在 OnBindViewHolder(); 方法内添加一个额外的 else 语句。

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
    // 从数据库列表中获取当前位置的数据库表
    AssignmentTable assignmentTable = assignmentList.get(position);
    // 实例化视图
    String due = "截止日期:" + assignmentTable.dueDate;
    String type = assignmentTable.type;
    holder.txtItemName.setText(assignmentTable.name);
    holder.txtItemDate.setText(due);
    holder.txtItemType.setText(type);
    // 将复选框设置为其保存的状态
    if (assignmentTable.isCompleted == true) {
        holder.checkBox.setChecked(true);
    } else {
        holder.checkBox.setChecked(false);
    }
    // 获取当前截止日期并解析
    Date currentDate = getCurrentDate();
    String dueDateAsString = assignmentTable.dueDate;
    Date dueDateOfCurrentAssignment = parseDate(dueDateAsString);
    // 以编程方式更改背景颜色
    if (currentDate.equals(dueDateOfCurrentAssignment)) {
        holder.txtItemDate.setText("截止日期:今天"); // 更改截止日期
        holder.txtItemDate.setTextColor(Color.parseColor("#ff0000"));
        holder.itemView.setBackgroundColor(Color.parseColor("#228b22")); // 更改颜色为绿色
        Log.d("已达到", assignmentTable.name + " 绿色背景");
    } else if (dueDateOfCurrentAssignment.before(currentDate)) {
        holder.itemView.setBackgroundColor(Color.parseColor("#8b0000")); // 背景变为红色
        holder.txtItemDate.setTextColor(Color.parseColor("#ff7a7a")); // 文本变为亮红色
        Log.d("已达到", assignmentTable.name + " 红色背景");
    } else {
        holder.itemView.setBackgroundColor(Color.parseColor("#191970"));
        holder.txtItemDate.setTextColor(Color.parseColor("#ff0000"));
        Log.d("已达到", assignmentTable.name + " 常规背景");
    }
    // 记录字段
    String assignment = "\n名称:" + assignmentTable.name + "\n截止日期:" + assignmentTable.dueDate + "\n类型:" +
            assignmentTable.type + "\n已完成:" + assignmentTable.isCompleted;
    Log.d("在ONBIND结束时", "\n" + assignment);
}
英文:

Fixed the issue! Turns out I just needed to add an extra else statement wihtin the OnBindViewHolder(); method

    @Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
//Fetching the database table at the current position from database list
AssignmentTable assignmentTable = assignmentList.get(position);
//Instantiating the views
String due = "Due: "+assignmentTable.dueDate;
String type = assignmentTable.type;
holder.txtItemName.setText(assignmentTable.name);
holder.txtItemDate.setText(due);
holder.txtItemType.setText(type);
//Setting the checkboxes to their saved state
if(assignmentTable.isCompleted == true){
holder.checkBox.setChecked(true);
}else {
holder.checkBox.setChecked(false);
}
//Fetching current due date and parsing
Date currentDate = getCurrentDate();
String dueDateAsString = assignmentTable.dueDate;
Date dueDateOfCurrentAssignment = parseDate(dueDateAsString);
//changing the background color programmatically
if(currentDate.equals(dueDateOfCurrentAssignment)){
holder.txtItemDate.setText("Due: Today"); //changes due date
holder.txtItemDate.setTextColor(Color.parseColor("#ff0000"));
holder.itemView.setBackgroundColor(Color.parseColor("#228b22")); // changes color to green
Log.d("REACHED", assignmentTable.name + " GREEN COLOR");
}else if(dueDateOfCurrentAssignment.before(currentDate)){
holder.itemView.setBackgroundColor(Color.parseColor("#8b0000")); // turns the background red
holder.txtItemDate.setTextColor(Color.parseColor("#ff7a7a")); // turns text bright red
Log.d("REACHED", assignmentTable.name + " RED COLOR");
}else{
holder.itemView.setBackgroundColor(Color.parseColor("#191970"));
holder.txtItemDate.setTextColor(Color.parseColor("#ff0000"));
Log.d("REACHED", assignmentTable.name + " REGULAR BACKGROUND");
}
//Logging fields
String assignment = "\nName: " + assignmentTable.name + "\nDue Date: " + assignmentTable.dueDate + "\nType: " +
assignmentTable.type + "\nCompleted: " + assignmentTable.isCompleted;
Log.d("AT END OF ONBIND", "\n" + assignment);
}

huangapple
  • 本文由 发表于 2020年9月27日 11:26:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/64084507.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定