使用Realm Android在Recyclerview中未存储编辑项目



我正在尝试创建一个任务应用程序,其中我将领域用作本地数据库。我正在Recyclerview中显示此任务。此刻,我可以添加一个带有标题,日期和时间的新任务。但是,当我尝试编辑项目时,RecyClerview不会更新。同样,在删除一项之后,列表显示错误。例如,如果我单击任务1,它在其中显示任务2,何时单击任务2,它显示了其中的任务1。我的addTaskActivity类是

编辑添加任务活动

public class TodoAddActivity extends AppCompatActivity {
// Variables
private Context mContext;
private Realm realm;
private TodoModel task;
private Button button;
private EditText mTaskNameEditText;
private EditText mTaskDateEditText;
private EditText mTaskTimeEditText;
String time;
private RealmResults<TodoModel> results;
public final static String INTENT_KEY_ID = "taskId";
public final static String DATE_FORMAT = "dd/MMM/yy";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView( R.layout.todo_add_layout);

    mContext = this;
    realm=Realm.getDefaultInstance();
    setUpUIViews();
    showData();
    final String taskId = getIntent().getStringExtra(INTENT_KEY_ID);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (taskId == null)
                addTask();
            else
                editTask(taskId);
        }
    });
    mTaskDateEditText.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            datePicker(view);
        }
    });
    mTaskDateEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View view, boolean b) {
            if (b)
                datePicker(view);
        }
    });
    mTaskTimeEditText.setOnClickListener( new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            timePicker( view );
        }
    } );
    mTaskTimeEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View view, boolean b) {
            if (b)
                timePicker( view );
        }
    });
    if (taskId != null) {
        fillTask(realm.where(TodoModel.class).equalTo("id", taskId).findFirst());
        button.setText("EDIT");
    }

}
private void setUpUIViews() {
    button = (Button) findViewById(R.id.activity_add_task_bt_add);
    mTaskNameEditText = (EditText) findViewById(R.id.activity_add_task_et_name);
    mTaskDateEditText = (EditText) findViewById(R.id.activity_add_task_et_date);
    mTaskTimeEditText = (EditText) findViewById(R.id.activity_add_task_et_time);
}
public void showData(){
     results = realm.where(TodoModel.class).findAll();
}
protected TodoModel getTask(int position) {
    return results.get(position);
}
private void fillTask(TodoModel task) {
    mTaskNameEditText.setText(task.getName());
    SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
    mTaskDateEditText.setText(sdf.format(task.getDate()));
    mTaskTimeEditText.setText(task.getTime());
}
private void addTask() {
    String taskName = mTaskNameEditText.getText().toString();
    String taskDate = mTaskDateEditText.getText().toString();
    String taskTime = mTaskTimeEditText.getText().toString();
    if (taskName.length() == 0 || taskName.equals("")) {
        mTaskNameEditText.setError("Should be filled");
        return;
    }
    if (taskDate.length() == 0 || taskDate.equals("")) {
        mTaskDateEditText.setError("Should be filled");
        return;
    }
    TodoModel task = getTask(taskName, taskDate,taskTime);
    if (task == null) {
        mTaskDateEditText.setError("Not a correct date");
        return;
    }
    task.setDone(false);
    addTask(task);
    setResult(RESULT_OK);
    finish();
}
protected void addTask(TodoModel task) {
    realm.beginTransaction();
    TodoModel newTask = realm.createObject(TodoModel.class, UUID.randomUUID().toString());
    newTask.setName(task.getName());
    newTask.setDate(task.getDate());
    newTask.setTime(task.getTime());
    realm.commitTransaction();
}
private void editTask(String taskId) {
    String taskName = mTaskNameEditText.getText().toString();
    String taskDate = mTaskDateEditText.getText().toString();
    String taskTime = mTaskTimeEditText.getText().toString();
    if (taskName.length() == 0 || taskName.equals("")) {
        mTaskNameEditText.setError("Should be filled");
        return;
    }
    if (taskDate.length() == 0 || taskDate.equals("")) {
        mTaskDateEditText.setError("Should be filled");
        return;
    }
    if (taskTime.length() == 0 || taskTime.equals("")) {
        mTaskTimeEditText.setError("Should be filled");
        return;
    }
    TodoModel task = getTask(taskName, taskDate,taskTime);
    if (task == null) {
        mTaskDateEditText.setError("Not a correct date");
        return;
    }
    task.setId(taskId);
    updateTask(task);
    setResult(RESULT_OK);
    finish();
}
protected void updateTask(TodoModel task) {
    realm.beginTransaction();
    TodoModel newTask = realm.where(TodoModel.class).equalTo("id", task.getId()).findFirst();
    newTask.setDate(task.getDate());
    newTask.setDone(task.isDone());
    newTask.setName(task.getName());
    realm.commitTransaction();
}

private void datePicker(final View view) {
    Calendar currentTime = Calendar.getInstance();
    int year = currentTime.get(Calendar.YEAR);
    int monthOfYear = currentTime.get(Calendar.MONTH);
    int dayOfMonth = currentTime.get(Calendar.DAY_OF_MONTH);
    DatePickerDialog mDatePickerDialog = new DatePickerDialog(mContext, 0, new DatePickerDialog.OnDateSetListener() {
        @Override
        public void onDateSet(DatePicker datePicker, int year, int monthOfYear, int dayOfMonth) {
            Calendar calendar = Calendar.getInstance();
            calendar.set(year, monthOfYear, dayOfMonth);
            SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
            ((EditText) view).setText(sdf.format(calendar.getTime()));
        }
    }, year, monthOfYear, dayOfMonth);
    mDatePickerDialog.setTitle("Select Time");
    mDatePickerDialog.show();
}
private void timePicker(final View view) {
    Calendar mcurrentTime = Calendar.getInstance();
    int hour = mcurrentTime.get(Calendar.HOUR_OF_DAY);
    int minute = mcurrentTime.get(Calendar.MINUTE);
    TimePickerDialog mTimePicker;
    mTimePicker = new TimePickerDialog(mContext,0, new TimePickerDialog.OnTimeSetListener() {
        @Override
        public void onTimeSet(TimePicker timePicker, int selectedHour, int selectedMinute) {
            mTaskTimeEditText.setText( selectedHour + ":" + selectedMinute);
        }
    }, hour, minute, true);//Yes 24 hour time
    mTimePicker.setTitle("Select Time");
    mTimePicker.show();
}

private TodoModel getTask(String name, String dateString,String time) {
    TodoModel task = new TodoModel();
    try {
        SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
        task.setName(name);
        task.setDate(sdf.parse(dateString));
        task.setTime(time );
        task.setDone(false);
        return task;
    } catch (ParseException e) {
        e.printStackTrace();
        return null;
    }
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId() == android.R.id.home)
        onBackPressed();
    return super.onOptionsItemSelected(item);
}

}

适配器类是

    public class TodoAdapter extends RealmRecyclerViewAdapter<TodoModel, TodoAdapter.TaskHolder> {
    public final static String INTENT_KEY_ID = "taskId";
    //public final static String INTENT_KEY_POSITION = "position";
    public final static String DATE_FORMAT = "dd/MMM/yy";
    private Realm realm;
    public interface TaskListener {
    }
    private final TaskListener taskListener;
    private final Context context;
    public TodoAdapter(TaskListener taskListener, RealmResults<TodoModel> realmResults, Context context, Realm realm) {
        super(realmResults, true);
        this.taskListener = taskListener;
        this.context = context;
        this.realm = realm;
    }
    @Override
    public TaskHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new TaskHolder( LayoutInflater.from(parent.getContext()).inflate(R.layout.todo_row, parent, false));
    }
    @Override
    public void onBindViewHolder(TaskHolder holder, final int position) {
        final TodoModel task = getData().get(position);
        holder.taskTextView.setText(task.getName());
        holder.doneCheckBox.setChecked(task.isDone());
        holder.timeTextView.setText( task.getTime() );
        final SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
        final Date date = (task.getDate());
        if (sdf.format(date).equals(sdf.format(getDate(0))))
            holder.dateTextView.setText("Today");
        else if (sdf.format(date).equals(sdf.format(getDate(-1))))
            holder.dateTextView.setText("Yesterday");
        else if (sdf.format(date).equals(sdf.format(getDate(1))))
            holder.dateTextView.setText("Tomorrow");
        else if (date.getTime() < getDate(6).getTime()) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            holder.dateTextView.setText( DateFormat.format("EEEE", calendar.getTime()).toString());
        } else
            holder.dateTextView.setText(sdf.format(task.getDate()));
        holder.cardView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(context, TodoAddActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.putExtra(INTENT_KEY_ID, getTask(position).getId());
                //intent.putExtra(INTENT_KEY_POSITION, position);
                context.startActivity(intent);
            }
        });
        holder.doneCheckBox.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                TodoModel task = new TodoModel();
                task.setId(getTask(position).getId());
                task.setDate(getTask(position).getDate());
                task.setName(getTask(position).getName());
                task.setDone(((CheckBox) v).isChecked());
                updateTask(position, task);
            }
        });
        holder.deleteImageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (getTask(position).isDone()) {
                    removeTask(position);
                    return;
                }
                AlertDialog.Builder alertDialog = new AlertDialog.Builder(context);
                alertDialog.setTitle("Confirm Delete?");
                alertDialog.setMessage("Do you want to delete the task you created?");
                alertDialog.setPositiveButton("YES", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.cancel();
                        removeTask(position);
                    }
                });
                alertDialog.setNegativeButton("NO", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.cancel();
                    }
                });
                alertDialog.show();
            }
        });
    }
    public class TaskHolder extends RecyclerView.ViewHolder {
        public CardView cardView;
        public TextView taskTextView;
        public TextView dateTextView;
        public TextView timeTextView;
        public ImageView deleteImageView;
        public CheckBox doneCheckBox;

        public TaskHolder(View itemView) {
            super(itemView);
            taskTextView = (TextView) itemView.findViewById( R.id.row_task_list_tv_name);
            dateTextView = (TextView) itemView.findViewById(R.id.row_task_list_tv_date);
            timeTextView=(TextView)itemView.findViewById( R.id.row_task_list_tv_time );
            deleteImageView = (ImageView) itemView.findViewById(R.id.row_task_list_iv_delete);
            doneCheckBox = (CheckBox) itemView.findViewById(R.id.row_task_list_cb_done);
            cardView = (CardView) itemView.findViewById(R.id.cardView);
        }
    }
    private Date getDate(int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, day);
        return calendar.getTime();
    }
    protected TodoModel getTask(int position) {
        return getData().get(position);
    }
    protected void updateTask(int position, TodoModel task) {
        realm.beginTransaction();
        TodoModel newTask = realm.where(TodoModel.class).equalTo("id", task.getId()).findFirst();
        newTask.setDate(task.getDate());
        newTask.setDone(task.isDone());
        newTask.setName(task.getName());
        realm.commitTransaction();
    }
    protected void removeTask(int position) {
        TodoModel newTask = realm.where(TodoModel.class).equalTo("id", getTask(position).getId()).findFirst();
        realm.beginTransaction();
        newTask.deleteFromRealm();
        realm.commitTransaction();
    }
}

主要片段

 public class ToDoListFragment extends Fragment implements TodoAdapter.TaskListener{
    private static final int ADD_TASK_REQUEST_CODE = 1000;
    private static final int EDIT_TASK_REQUEST_CODE = 1001;
    private Realm realm;
    private RecyclerView recyclerView;
    private TodoAdapter adapter;
    public ToDoListFragment() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View rootView = inflater.inflate(R.layout.fragment_todo_layout, container, false);
        // Views
        FloatingActionButton addFloatingActionButton = (FloatingActionButton) rootView.findViewById(R.id.activity_tasks_fab_add);
        //Listeners
        addFloatingActionButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivityForResult(new Intent(getActivity(), TodoAddActivity.class), ADD_TASK_REQUEST_CODE);
            }
        });
        return rootView;
    }
    @Override
    public void onViewCreated(View view,Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        realm = Realm.getDefaultInstance();
        recyclerView = (RecyclerView) view.findViewById(R.id.activity_tasks_ll_task);
        recyclerView.setHasFixedSize(true);
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity());
        recyclerView.setLayoutManager(layoutManager);
        setAdapter();
    }
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
    }
    @Override
    public void onPrepareOptionsMenu(Menu menu) {
        menu.findItem(R.id.blu_home).setVisible(true);
        super.onPrepareOptionsMenu(menu);
    }
    private void setAdapter() {
        adapter = new TodoAdapter(this,realm.where(TodoModel.class).findAllSortedAsync("name"),getActivity(), realm);
        recyclerView.setAdapter(adapter);
        adapter.notifyDataSetChanged();
    }
    private void setUpRecycler() {
        recyclerView.setHasFixedSize(true);
        final LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
        layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(layoutManager);
        setAdapter();
    }
}

image1

image2

logcat

09-06 18:49:36.227 3214-3214/demo.app.com.bluapp_client_and E/AndroidRuntime: FATAL EXCEPTION: main
                                                                          Process: demo.app.com.bluapp_client_and, PID: 3214
                                                                          java.lang.ArrayIndexOutOfBoundsException: Out of range  in /home/cc/repo/realm/release/realm/realm-library/src/main/cpp/io_realm_internal_Collection.cpp line 152(requested: 1 valid: 1)
                                                                              at io.realm.internal.Collection.nativeGetRow(Native Method)
                                                                              at io.realm.internal.Collection.getUncheckedRow(Collection.java:410)
                                                                              at io.realm.OrderedRealmCollectionImpl.get(OrderedRealmCollectionImpl.java:111)
                                                                              at io.realm.RealmResults.get(RealmResults.java:60)
                                                                              at io.realm.OrderedRealmCollectionImpl.get(OrderedRealmCollectionImpl.java:21)
                                                                              at demo.app.com.bluapp_client_and.adapter.TodoAdapter.getTask(TodoAdapter.java:154)
                                                                              at demo.app.com.bluapp_client_and.adapter.TodoAdapter$3.onClick(TodoAdapter.java:103)
                                                                              at android.view.View.performClick(View.java:5610)
                                                                              at android.view.View$PerformClick.run(View
public class TodoAddActivity extends AppCompatActivity {
    // Variables
    private Context mContext;
    private Realm realm;
    private TodoModel task;
    private Button button;
    private EditText mTaskNameEditText;
    private EditText mTaskDateEditText;
    private EditText mTaskTimeEditText;
    String time;
    //private static List<TodoModel> tasks;
    private RealmResults<TodoModel> results;
    public final static String INTENT_KEY_ID = "taskId";
    public final static String DATE_FORMAT = "dd/MMM/yy";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView( R.layout.todo_add_layout);
        mContext = this;
        realm=Realm.getDefaultInstance();
        setUpUIViews();
        showData();
        final String taskId = getIntent().getStringExtra(INTENT_KEY_ID);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (taskId == null)
                    addTask();
                else
                    editTask(taskId);
            }
        });
        mTaskDateEditText.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                datePicker(view);
            }
        });
        mTaskDateEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View view, boolean b) {
                if (b)
                    datePicker(view);
            }
        });
        mTaskTimeEditText.setOnClickListener( new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                timePicker( view );
            }
        } );
        mTaskTimeEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View view, boolean b) {
                if (b)
                    timePicker( view );
            }
        });
        if (taskId != null) {
            fillTask(realm.where(TodoModel.class).equalTo("id", taskId).findFirst());
            button.setText("EDIT");
        }
    }
    private void setUpUIViews() {
        button = (Button) findViewById(R.id.activity_add_task_bt_add);
        mTaskNameEditText = (EditText) findViewById(R.id.activity_add_task_et_name);
        mTaskDateEditText = (EditText) findViewById(R.id.activity_add_task_et_date);
        mTaskTimeEditText = (EditText) findViewById(R.id.activity_add_task_et_time);
    }
    public void showData(){
        //tasks = new ArrayList<>(); //error
        //RealmResults<TodoModel> tasksResult = realm.where(TodoModel.class).findAll();
        //for (TodoModel task : tasksResult)
        //    tasks.add(task); //error*/
        results = realm.where(TodoModel.class).findAll();
    }
    protected TodoModel getTask(int position) {
        return results.get(position);
    }
    private void fillTask(TodoModel task) {
        mTaskNameEditText.setText(task.getName());
        SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
        mTaskDateEditText.setText(sdf.format(task.getDate()));
        mTaskTimeEditText.setText(task.getTime());
    }
    private void addTask() {
        String taskName = mTaskNameEditText.getText().toString();
        String taskDate = mTaskDateEditText.getText().toString();
        String taskTime = mTaskTimeEditText.getText().toString();
        if (taskName.length() == 0 || taskName.equals("")) {
            mTaskNameEditText.setError("Should be filled");
            return;
        }
        if (taskDate.length() == 0 || taskDate.equals("")) {
            mTaskDateEditText.setError("Should be filled");
            return;
        }
        TodoModel task = getTask(taskName, taskDate,taskTime);
        if (task == null) {
            mTaskDateEditText.setError("Not a correct date");
            return;
        }
        task.setDone(false);
        addTask(task);
        setResult(RESULT_OK);
        finish();
    }
    protected void addTask(TodoModel task) {
        realm.beginTransaction();
        TodoModel newTask = realm.createObject(TodoModel.class, UUID.randomUUID().toString());
        newTask.setName(task.getName());
        newTask.setDate(task.getDate());
        newTask.setTime(task.getTime());
        //realm.copyToRealmOrUpdate(newTask);
        realm.commitTransaction();
        //realm.close();
    }
    private void editTask(String taskId) {
        String taskName = mTaskNameEditText.getText().toString();
        String taskDate = mTaskDateEditText.getText().toString();
        String taskTime = mTaskTimeEditText.getText().toString();
        if (taskName.length() == 0 || taskName.equals("")) {
            mTaskNameEditText.setError("Should be filled");
            return;
        }
        if (taskDate.length() == 0 || taskDate.equals("")) {
            mTaskDateEditText.setError("Should be filled");
            return;
        }
        if (taskTime.length() == 0 || taskTime.equals("")) {
            mTaskTimeEditText.setError("Should be filled");
            return;
        }
        TodoModel task = getTask(taskName, taskDate,taskTime);
        if (task == null) {
            mTaskDateEditText.setError("Not a correct date");
            return;
        }
        task.setId(taskId);
        updateTask(task);
        setResult(RESULT_OK);
        finish();
    }
    protected void updateTask(TodoModel task) {
        realm.beginTransaction();
        TodoModel newTask = realm.where(TodoModel.class).equalTo("id", task.getId()).findFirst();
        newTask.setDate(task.getDate());
        newTask.setDone(task.isDone());
        newTask.setName(task.getName());
        realm.commitTransaction();
    }

    private void datePicker(final View view) {
        Calendar currentTime = Calendar.getInstance();
        int year = currentTime.get(Calendar.YEAR);
        int monthOfYear = currentTime.get(Calendar.MONTH);
        int dayOfMonth = currentTime.get(Calendar.DAY_OF_MONTH);
        DatePickerDialog mDatePickerDialog = new DatePickerDialog(mContext, 0, new DatePickerDialog.OnDateSetListener() {
            @Override
            public void onDateSet(DatePicker datePicker, int year, int monthOfYear, int dayOfMonth) {
                Calendar calendar = Calendar.getInstance();
                calendar.set(year, monthOfYear, dayOfMonth);
                SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
                ((EditText) view).setText(sdf.format(calendar.getTime()));
            }
        }, year, monthOfYear, dayOfMonth);
        mDatePickerDialog.setTitle("Select Time");
        mDatePickerDialog.show();
    }
    private void timePicker(final View view) {
        Calendar mcurrentTime = Calendar.getInstance();
        int hour = mcurrentTime.get(Calendar.HOUR_OF_DAY);
        int minute = mcurrentTime.get(Calendar.MINUTE);
        TimePickerDialog mTimePicker;
        mTimePicker = new TimePickerDialog(mContext,0, new TimePickerDialog.OnTimeSetListener() {
            @Override
            public void onTimeSet(TimePicker timePicker, int selectedHour, int selectedMinute) {
                mTaskTimeEditText.setText( selectedHour + ":" + selectedMinute);
            }
        }, hour, minute, true);//Yes 24 hour time
        mTimePicker.setTitle("Select Time");
        mTimePicker.show();
    }

    private TodoModel getTask(String name, String dateString,String time) {
        TodoModel task = new TodoModel();
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
            task.setName(name);
            task.setDate(sdf.parse(dateString));
            task.setTime(time );
            task.setDone(false);
            return task;
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == android.R.id.home)
            onBackPressed();
        return super.onOptionsItemSelected(item);
    }
}

最新更新