从零开始写一个Android待办事项ToDoListApp

从零开始写一个Android待办事项ToDoListApp,第1张

概述 初衷

作为一个程序员,每天要处理的事项越来越多,有时一件事情花费了太多的时间而忽略了还有其他事情等着处理。开始是借助Microsoft ToDo 来记录下待办事项,时不时的去看一下,勾选掉已经完成,未完成暴露在面前就能分清轻重缓急而不至于漏掉。搞不懂最近更新什么东西,使用起来问题很多,还是自已撸一个得了,而且很多待办也属于自己的隐私,老是上传他们的云端也感觉不那个。

解决方案

本着借鉴和越简单越好的精神,直接使用RecyclerView列表控件来完成待办事项的展示和记录。
有时一个问题的处理可能需要的周期比较长,需要分步进行,再加上个子项目的功能。
已经完成的事情可能还需要回查,那就除了待办列表外,再加上个已完成的列表在需要的时候可以展示。
云端功能是好,但。。。暂不添加同步功能。

效果图

请忽略美工,本着实用简单为前提,够用就好。

开撸 Bean

数据实体类最能反映解决思路,先放上bean类
这里借用了GreenDao来处理数据库方面的增删改查

因为要传值,所以最后把实体序列化可能需要不同的待办列表,通过一个item表来管理,你也可以写死在代码里子项目与父项目的结构差不多,不想再搞一个表,直接通过type类型来区分状态用来管理是否已完成
@Entity(nameInDb = "tb_todo")
public class ToDoListEntity implements Serializable {
    private static final long serialVersionUID = -8812106798197363961L;
    @Id(autoincrement = true)
    private Long id;
    private String todo_item; //待办类型:工作,个人
    private Integer todo_type; //列表类型:0标题,1子项目
    private String todo_no; //项目编号:yyyyMMddHHmmss 14位
    private Integer todo_ser; //子项目排序从1开始,标题排序为0
    private String todo_content; //项目内容
    private Integer todo_status; //是否完成:0未完成,1已完成
}
ViewModel 是个好东西

接口继承请忽略,我是加入了一个MVP+ViewModel的代码架构,本着多学习多尝试的原则,小项目咱也用上了大架构,实际开发中非必需。

public class ToDoListModel extends ViewModel implements ToDoListContract.M {
    private MutableLiveData<List<ToDoListEntity>> listToDo; //取得待办列表
    private MutableLiveData<List<ToDoListEntity>> listFinish; //取得已完成列表
    private MutableLiveData<List<ToDoListEntity>> listDetail; //取得子项目列表
    private MutableLiveData<List<ReferItemEntity>> items; //取得待办类型
}
 mModel.getListToDo().observe(this, toDoListEntities -> {
     toDoListEntityList.clear();
     toDoListEntityList.addAll(toDoListEntities);
     toDoListAdapter.notifyDataSetChanged();
 });
 mModel.getListFinish().observe(this, toDoListEntities -> {
     toDoListEntityListFinish.clear();
     toDoListEntityListFinish.addAll(toDoListEntities);
     toDoListAdapterFinish.notifyDataSetChanged();
 });
 mPresenter.getItems("todo_item");
 mModel.getItems().observe(this, referItemEntities -> {
     toDoItemList.clear();
     toDoItemList.addAll(referItemEntities);
     bindingView.tabTodoItem.removeAllTabs();
     for (ReferItemEntity referItemEntity : toDoItemList) {
         bindingView.tabTodoItem.addTab(bindingView.tabTodoItem.newTab().setText(referItemEntity.getItem_name()));
     }
 });
已完成列表
//显示已完成项目
bindingView.tvTodoFinishLabel.setOnClickListener(view -> {
    if (bindingView.rvTodoFinish.getVisibility() == View.VISIBLE) {
        bindingView.rvTodoFinish.setVisibility(View.GONE);
        bindingView.ivToDoFinishTag.setImageDrawable(ContextCompat.getDrawable(ToDoListActivity.this, R.drawable.ic_find_previous_holo_dark));
    } else {
        mPresenter.getListFinish(todo_item);
        bindingView.rvTodoFinish.setVisibility(View.VISIBLE);
        bindingView.ivToDoFinishTag.setImageDrawable(ContextCompat.getDrawable(ToDoListActivity.this, R.drawable.ic_find_next_holo_dark));
    }
});
bindingView.ivToDoFinishTag.setOnClickListener(view -> bindingView.tvTodoFinishLabel.performClick());
绑定监听事件
bindingView.btnTodoAdd.setOnClickListener(view -> toDoEdit(-1, false));
toDoListAdapter.setItemClickListener(position -> toDoEdit(position, false));
toDoListAdapter.setItemRemoveListener(position -> toDoDelete(position, false));
toDoListAdapter.setItemFinishListener(position -> toDoFinish(position, false));
子项目

入在编辑界面中,通过点击父项目打开一个Fragmentg来编辑保存

private void getToDoList() {
    Bundle bundle = this.getArguments();
    if (bundle != null) {
        toDoListEntity = (ToDoListEntity) bundle.getSerializable("todo");
    } else {
        showError("非法入口,请退出重新 *** 作!");
        this.getActivity().onBackPressed();
    }
    //处理传进来的数据
    _id = toDoListEntity.getId();
    if (_id != null) {
        mPresenter.getListDetail(toDoListEntity.getTodo_item(), toDoListEntity.getTodo_no());
    }
    bindingView.editToDoContent.setText(toDoListEntity.getTodo_content());
}
mModel.getListDetail().observe(this, list -> {
    toDoListEntitySubList.clear();
    toDoListEntitySubList.addAll(list);
    toDoListAdapter.notifyDataSetChanged();
});
补充 CheckBox

特别拉出来提一嘴,在列表中使用CheckBox来更新完成状态时,如果同时更新列表可能会出现错误提示
Cannot call this method while RecyclerView is computing a layout or scrolling
原因呢?
在RecyclerView中使用CheckBox来处理移除等事件时,会导致锁定状态问题,较好的解决方案是避免使用 setOnCheckedChangeListener 而改为使用 setOnClickListener 监听点击事件

notifyItemRemoved

RecyclerView中移除项目后调用这个方法可以出现移除动画,但实际开发中,发现索引会出错,列表数据并没有跟着更新,当下的处理方式最好通知Adapter更新一个数据 notifyDataSetChanged

toDoListAdapter.setItemRemoveListener(position -> {
    showDialogAsk("是否确认删除?", (dialogInterface, i) -> {
        mPresenter.toDoDelete(toDoListEntitySubList.get(position));
        toDoListEntitySubList.remove(position);
        toDoListAdapter.notifyItemRemoved(position);
        toDoListAdapter.notifyDataSetChanged();
    });
});

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/992477.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存