房间里的RecyclerView重复元素

时间:2018-08-13 16:52:55

标签: android android-recyclerview android-room

我正在学习使用Room在Android上制作持久数据。对于本课程,我必须创建一个“待办事项列表”应用程序,该应用程序显示用户可以创建,删除和更新的待办事项列表。

当我必须更新显示给用户的待办事项列表时,我的问题就出现了,有时候我的RecyclerView从数据库中复制了一个元素,而不是显示刚刚创建的用户。

TaskEntry类(待办事项)

import android.arch.persistence.room.Entity;
import android.arch.persistence.room.Ignore;
import android.arch.persistence.room.PrimaryKey;

@Entity(tableName = "task")
public class TaskEntry {

    @Ignore
    public static final int PRIO_HIGH = 1;
    @Ignore
    public static final int PRIO_MED = 2;
    @Ignore
    public static final int PRIO_LOW = 3;

    @PrimaryKey(autoGenerate = true)
    private int mId;
    private int mPriority;
    private String mTaskName;
    private String mUpdateDate;

    @Ignore
    public TaskEntry(String name, int priority, String updateDate){
        mTaskName = name;
        mPriority = priority;
        mUpdateDate = updateDate;
    }

    public TaskEntry(int id, String taskName, int priority, String updateDate){
        mId = id;
        mTaskName = taskName;
        mPriority = priority;
        mUpdateDate = updateDate;
    }

    public void setId(int id){this.mId = id;}
    public int  getId()      {return mId;}

    public void setPriority(int p){this.mPriority = p;}
    public int  getPriority()     {return mPriority;}

    public void   setTaskName(String n){this.mTaskName = n;}
    public String getTaskName()        {return mTaskName;}

    public void   setUpdateDate(String ud){this.mUpdateDate = ud;}
    public String getUpdateDate()         {return mUpdateDate;}
}

我的道

import android.arch.persistence.room.Dao;
import android.arch.persistence.room.Delete;
import android.arch.persistence.room.Insert;
import android.arch.persistence.room.OnConflictStrategy;
import android.arch.persistence.room.Query;
import android.arch.persistence.room.Update;

import java.util.List;

@Dao
public interface TaskDao {

    @Query("SELECT * FROM task ORDER BY mPriority")
    List<TaskEntry> loadAllTasks();

    @Insert
    void insertTask(TaskEntry taskEntry);

    @Update(onConflict =  OnConflictStrategy.REPLACE)
    void updateTask(TaskEntry taskEntry);

    @Delete
    void deleteTask(TaskEntry taskEntry);

}

正如您在这里看到的那样,当我查询元素时,我要求这些元素按优先级排序,从我观察到的结果来看,当我添加一个元素的优先级高于最后添加的元素的优先级时,就会发生重复(因为应用程序(重新)启动)

此处是根据用户要求(在活动调用AddTaskActivity中)创建新的待办事项的功能

public void onSaveButtonClicked() {
    String name = mEditText.getText().toString();
    int valPrio = getPriorityFromViews();
    String date = dateFormat.format(Calendar.getInstance().getTime());

    Log.e(TAG, "New task : " + name + " prio " + valPrio + " date " + date);

    TaskEntry taskEntry = new TaskEntry(name, valPrio, date);

    mDB.taskDao().insertTask(taskEntry);
    finish();
}

我从日志消息中知道新对象是用正确的数据创建的,所以问题不在于读取用户输入

MainActivity.onResume(在onSaveButtonClicked之后调用)

@Override
protected void onResume() {
    mTaskAdapter.setTaskEntries(mDB.taskDao().loadAllTasks());
    super.onResume();
}

这是适配器:

import android.content.Context;
import android.graphics.drawable.GradientDrawable;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.example.tomga.to_dolist.database.TaskEntry;

import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Locale;

import static android.provider.Settings.System.DATE_FORMAT;
import static android.support.v4.content.ContextCompat.getColor;

public class TaskAdapter extends RecyclerView.Adapter<TaskAdapter.TaskViewHolder> {

    private static final String DATE_FORMAT ="dd/MM/yyyy";

    final private ItemClickListener mItemClickListener;
    private List<TaskEntry> mTaskEntries;
    private Context mContext;
    private SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT, Locale.getDefault());

    public TaskAdapter(Context context, ItemClickListener listener){
        mContext = context;
        mItemClickListener = listener;
    }

    @NonNull
    @Override
    public TaskViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(mContext).inflate(R.layout.task_layout, parent, false);
        return new TaskViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull TaskViewHolder holder, int position) {
        TaskEntry taskEntry = mTaskEntries.get(position);

        holder.id = taskEntry.getId();

        String tName = taskEntry.getTaskName();
        String tDate = taskEntry.getUpdateDate();
        int tPrio_int = taskEntry.getPriority();
        String tPrio = String.valueOf(tPrio_int);

        Log.e("bindingViews", "binding view : " + tName + " " + tPrio + " " + tDate);

        holder.mTaskName.setText(tName);
        holder.mUpdateDate.setText(tDate);

        holder.mPriorityView.setText(tPrio);
        GradientDrawable priorityCircle = (GradientDrawable) holder.mPriorityView.getBackground();
        priorityCircle.setColor( getPriorityColor(tPrio_int) );
    }

    @Override
    public int getItemCount() {
        if(mTaskEntries == null) return 0;

        return mTaskEntries.size();
    }

    private int getPriorityColor(int priority) {
        int priorityColor = 0;

        switch (priority) {
            case TaskEntry.PRIO_HIGH:
                priorityColor = ContextCompat.getColor(mContext, R.color.materialRed);
                break;
            case TaskEntry.PRIO_MED:
                priorityColor = ContextCompat.getColor(mContext, R.color.materialOrange);
                break;
            case TaskEntry.PRIO_LOW:
                priorityColor = ContextCompat.getColor(mContext, R.color.materialYellow);
                break;
            default:
                break;
        }
        return priorityColor;
    }

    public void setTaskEntries(List<TaskEntry> TE){
        mTaskEntries = TE;
    }

    public interface ItemClickListener{
        void onItemClickListener(int itemId);
    }


    public class TaskViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        TextView mTaskName;
        TextView mUpdateDate;
        TextView mPriorityView;
        int id;

        public TaskViewHolder(View itemView){
            super(itemView);

            mTaskName = itemView.findViewById(R.id.task_name);
            mUpdateDate = itemView.findViewById(R.id.task_update_date);
            mPriorityView = itemView.findViewById(R.id.priority_circle);
            itemView.setOnClickListener(this);
        }

        @Override
        public void onClick(View view) {
            int elemId = mTaskEntries.get(getAdapterPosition()).getId();
            mItemClickListener.onItemClickListener(elemId);
        }
    }

    public TaskEntry getTaskFromId(int id){return mTaskEntries.get(id);}
}

如果您需要代码中的任何其他信息,我会提供(我试图尽可能缩短它,以便可能缺少一些重要的内容)

0 个答案:

没有答案