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

概述

初衷

作为一个程序员,每天要处理的事项越来越多,有时一件事情花费了太多的时间而忽略了还有其他事情等着处理。开始是借助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();
    });
});
  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
从零开始Android的SystemUI,需要具备一些基本的知识和技能。首先,你需要熟悉Java编程语言和Android开发的基础知识。了解Android的Activity、Service、BroadcastReceiver等组件的用法和生命周期。 接下来,你需要理解SystemUI是Android系统的一部分,是用于管理和显示系统状态栏、导航栏等界面元素的应用程序。它需要与底层系统进行交互,并实现对其进行控制和更新。你可以参考Android源代码中的SystemUI模块,了解其结构和基本原理。 在编SystemUI之前,可以先定义你的项目目标和需求。你可以思考你想实现的功能和界面样式。然后,创建一个新的Android项目,并启动一个新的进程用于运行SystemUI。你可以在AndroidManifest.xml文件中注册你的SystemUI服务组件。 接下来,你可以开始编SystemUI的代码。你可以创建一个主Activity来加载和管理系统状态栏和导航栏的布局。可以使用Android提供的View类来创建和显示界面元素。你还可以利用Android系统提供的API来获取和更新系统状态信息。 在编SystemUI时,你需要考虑到系统UI的响应性和性能。你可以使用线程和异步任务来处理后台操作,以避免阻塞UI线程。此外,你还可以使用Android的Notification和Broadcast机制与其他应用程序进行通信。 最后,你可以进行调试和测试你的SystemUI应用程序。你可以使用Android设备或模拟器来运行你的应用,并逐步验证功能的正确性和稳定性。 总结而言,从零开始Android的SystemUI需要对Android开发有一定的了解和经验。通过学习Android的基础知识、阅读源代码、分析需求和目标,你可以逐步构建一个可靠和功能丰富的SystemUI应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值