step1:创建Todo类
public class Todo {
private String content;
private int ddl;
private boolean selected;
public Todo(String content) {
this.content = content;
this.selected = false;
}
public String getContent() {
return content;
}
public int getDdl() {
return ddl;
}
public void setContent(String content) {
this.content = content;
}
public void setDdl(int ddl) {
this.ddl = ddl;
}
public boolean getSelected() {
return selected;
}
public void setSelected(boolean b){
this.selected = b;
}
}
step2:添加recyclarView
创建recyclarView的过程这里不再赘述,效果如下
step3:实现todo的点击效果
在adapter的onBindViewHolder()中添加点击事件
holder.todoContent.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
todo.setSelected(b);
if (b) {
holder.todoContent.getPaint().setFlags(Paint.STRIKE_THRU_TEXT_FLAG);//添加中划线
holder.todoContent.setTextColor(Color.parseColor("#C0C0C0"));//修改字体颜色
} else {
holder.todoContent.getPaint().setFlags(0);//恢复无划线
holder.todoContent.setTextColor(Color.parseColor("#000000"));//恢复字体颜色
}
mTodoList.set(i, todo);
}
});
实现效果如下:
step4:添加悬浮按钮以及添加todo事件
如何添加悬浮按钮这里不再阐述,效果如下:
在添加对应的点击事件时,一开始我打算将布局放在fragment上,但是在弹出返回栈时会直接切换到Diary界面。
于是选择通过新建activity实现,但是新建activity后原来todo界面的背景会被activity的背景覆盖,不太美观。
最后,我们决定通过popupWindow实现,这样就一次性解决了返回退出的几个问题。相关代码:
public void load_popupwindow(){
View popView = getLayoutInflater().inflate(R.layout.fragment_add_todo, null);
popupTodoAdd=new PopupWindow(popView, (int) (binding.getRoot().getWidth() * 0.8),
ViewGroup.LayoutParams.WRAP_CONTENT);
popupTodoAdd.setBackgroundDrawable(ResourcesCompat.getDrawable(getResources(),
R.drawable.round_outline, null));
popupTodoAdd.setOutsideTouchable(true);//点击其它退出
popupTodoAdd.setFocusable(true);//可编辑todo
popupTodoAdd.setAnimationStyle(R.style.popupWindow_anim_style);//设置动画
//设置点击事件
EditText editText = popView.findViewById(R.id.todo_edit);
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
Log.d("todo content",charSequence.toString());
}
@Override
public void afterTextChanged(Editable editable) {
}
});
Button button = popView.findViewById(R.id.add_todo_button);
button.setOnClickListener(view1 -> {
Toast.makeText(getContext(),"已保存",Toast.LENGTH_SHORT).show();
// EventBus.getDefault().post(editText.getText().toString());
todoList.add(0,new Todo(editText.getText().toString()));//将todo添加到第一个
refreshTodo();
popupTodoAdd.dismiss();
});
popupTodoAdd.showAtLocation(binding.getRoot(), Gravity.CENTER, 0, 0);
}
实现效果:

step5:将TODO添加到数据库
除了database和Dao类之外,在这里我还定义了一个TodoEngine类用于简化todo增删改查的操作,代码如下:
public class TodoEngine {
final TodoDao todoDao;
public TodoEngine(Context context) {
TodoDatabase todoDatabase = TodoDatabase.getInstance(context);
todoDao = todoDatabase.getTodoDao();
}
//插入
public void insertTodo(Todo... todos) {
new InsertAsyncTack(todoDao).execute(todos);
}
static class InsertAsyncTack extends AsyncTask<Todo, Void, Void> {
final TodoDao dao;
public InsertAsyncTack(TodoDao todoDao) {
dao = todoDao;
}
@Override
protected Void doInBackground(Todo... todos) {
dao.insertTodo(todos);
return null;
}
}
//更新
public void updateTodos(Todo... todos) {
new UpdateAsyncTack(todoDao).execute(todos);
}
static class UpdateAsyncTack extends AsyncTask<Todo, Void, Void> {
final TodoDao dao;
public UpdateAsyncTack(TodoDao todoDao) {
dao = todoDao;
}
@Override
protected Void doInBackground(Todo... todos) {
dao.updateTodos(todos);
return null;
}
}
//删除
public void deleteTodos(Todo... todos) {
new DeleteAsyncTack(todoDao).execute(todos);
}
static class DeleteAsyncTack extends AsyncTask<Todo, Void, Void> {
private TodoDao dao;
public DeleteAsyncTack(TodoDao todoDao) {
dao = todoDao;
}
@Override
protected Void doInBackground(Todo... todos) {
dao.deleteTodos(todos);
return null;
}
}
//全部删除
public void deleteAll() {
new DeleteAllAsyncTack(todoDao).execute();
}
static class DeleteAllAsyncTack extends AsyncTask<Void, Void, Void> {
private TodoDao dao;
public DeleteAllAsyncTack(TodoDao todoDao) {
dao = todoDao;
}
@Override
protected Void doInBackground(Void... voids) {
dao.deleteAll();
return null;
}
}
//查询
public List<Todo> queryAllTodos() {
List<Todo> todoList = null;
try {
todoList = new QueryAsyncTack(todoDao).execute().get();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return todoList;
}
static class QueryAsyncTack extends AsyncTask<Void, Void, List<Todo>> {
private TodoDao dao;
public QueryAsyncTack(TodoDao todoDao) {
dao = todoDao;
}
@Override
protected List<Todo> doInBackground(Void... voids) {
List<Todo> todoList = dao.getAll();
for (Todo todo : todoList) {
Log.i("TODO", todo.toString());
}
return todoList;
}
}
}
step6:通过itemTouchHelper实现拖拽效果
定义todoItemTouchHelper继承自itemTouchHelper并且重写某些方法
在adapter中重写onItemMove和onItemDismiss实现todo项在recyclerView和数据库中的更新。