成电微记(五)TODO界面的实现


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的过程这里不再赘述,效果如下

1

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和数据库中的更新。


Author: Xi Chen
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint polocy. If reproduced, please indicate source Xi Chen !
评论
  TOC