我正在学习使用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);}
}
如果您需要代码中的任何其他信息,我会提供(我试图尽可能缩短它,以便可能缺少一些重要的内容)