在别人代码的基础上做了一个AndroidTodo


在别人代码的基础上做了一个AndroidTodo

一个简单的安卓todo应用,这个应用主要是从一位法国(注释是法语)的安卓开发者哪里来的灵感,我在原来的基础上增加了一个垃圾桶的功能,用户可以隐藏和找回自己已经完成的任务。

首先贴出原作者的仓库地址
https://github.com/KamilMichalski0/TodoListAndroid

本文仓库地址
https://github.com/whp98/TodoListAndroid

这里说明一下由于改动了包名所以没脸去原作者那里拉请求,没准后面改回去,本文主要是v1.0.0版本的内容。

目前包名已经改回去了,版本是v1.1.0更改了配色,见下文。并且申请和原作者合并,至于它同不同意就是后话了。

App演示

icon(网上找的非商用)

主界面

创建新的任务

回收站内容

通知栏发送通知

v1.1.0 最新版配色

技术实现

主要技术栈:SQLite数据库+Service+菜单设计+通知+复杂Adapter设计

数据库

数据库部分主要是一个数据库的操作,为了简化数据库的操作部分和减少数据库操作的失误几率这里使用数据库映射工具来实现数据库的操作,数据库操作主要使用
com.j256.ormlite包来完成
操作数据库的实体类
包含一些数据标记的注解

//任务实例类
@DatabaseTable(tableName = "todo_task")
public class TodoTask {

    @DatabaseField(generatedId = true)
    private int id;
    @DatabaseField(canBeNull = false)
    private String name;
    @DatabaseField
    private String note;
    @DatabaseField(canBeNull = false)
    private boolean done;
    @DatabaseField(canBeNull = false)
    private boolean hiden;
    @DatabaseField(canBeNull = false)
    private Date dateCreated;
    @DatabaseField(canBeNull = false)
    private boolean reminder;
    @DatabaseField
    private Date reminderDate;

创建数据库的Helper类,根据实体自重创建数据库

public class TodoDbOpenHelper extends OrmLiteSqliteOpenHelper {

    public static final String DATABASE_NAME = "todo.db";
    public static final int DATABASE_VERSION = 3;

    public TodoDbOpenHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase database, ConnectionSource connectionSource) {
        try {
            TableUtils.createTable(connectionSource,TodoTask.class);
        } catch (SQLException e) {
            e.printStackTrace();
        }

}

操作数据库的接口,在另一个类中具体实现数据操作

public interface ITaskDataBase {
    List<TodoTask> getTasks();

    List<TodoTask> getTasksHid();

    List<TodoTask> getFutureTasksWithReminder(Date now);

    void addTask(TodoTask task);

    TodoTask getTask(int position);

    void updateTask(TodoTask task, int position);

    void deleteTask(TodoTask task, int position);
}

数据库操作实现实现接口一个方法例子

//不显示隐藏的项目
    @Override
    public List<TodoTask> getTasks() {
        try {
            return mDao.queryBuilder()
                    .orderBy("done",true)
                    .orderBy("dateCreated",false)
                    .where().eq("hiden",false)
                    .query();
        } catch (SQLException e) {
            e.printStackTrace();
    }
        return Collections.emptyList();
    }

Adapter

使用第三方库butterknife来实现绑定控件

@BindView(R.id.task_done)
        CheckBox mDone;
        @BindView(R.id.task_title)
        TextView mTitle;
        @BindView(R.id.todoitem_hiddden)

设置数据和数据更新

public void setmTask(List<TodoTask> mTask) {
        this.mTask = mTask;
        notifyDataSetChanged();
}

使用viewholder实现控件复用提高性能

@Override
    public TodoViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View rowView = inflater.inflate(R.layout.list_item_todo, parent, false);
        return new TodoViewHolder(rowView);

    }

绑定viewholder

@Override
    public void onBindViewHolder(TodoViewHolder holder, int position) {
        TodoTask task = mTask.get(position);
        holder.mBlockListeners=true;
        holder.mCurrentPosition = task.getId();
        holder.mCurrentTask = task;
        holder.mTitle.setText(task.getName());
        holder.mDone.setChecked(task.getDone());
……

Bufferknife绑定监听器

@OnClick
        void onItemClick() {
            if (mClickListener != null && !mBlockListeners) {
                mClickListener.onClick(mCurrentTask, mCurrentPosition);
            }
        }

定义外部接口,activity实现该接口实现通信

public interface OnClickListener {
        void onClick(TodoTask task, int position);
        void onTaskHiddenChanged(TodoTask task,int position,boolean isHidden);
        void onTaskDoneChanged(TodoTask task, int position, boolean isDone);
    }

菜单

<item
        android:id="@+id/hidden_task"
        android:title="@string/menu_done_task"
        android:icon="@drawable/trashbin50px"
        app:showAsAction="ifRoom"/>
    <item
        android:id="@+id/menu_item_create"
        android:title="@string/nemu_add_task"
        android:icon="@drawable/new_menu"
        app:showAsAction="always" />

Service

设置通知的计划,这个任务会将任务交给负责通知的Service

public void planNotifications() {
        List<TodoTask> tasks = mTaskDatabase.getFutureTasksWithReminder(new Date());
        AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
        for (TodoTask task : tasks) {
            Intent serviceIntent = new Intent(mContext, TodoNotificationService.class);
            serviceIntent.putExtra("id", task.getId());
            PendingIntent pendingIntent = PendingIntent.getService(mContext,
                    task.getId(),
                    serviceIntent,
                    PendingIntent.FLAG_UPDATE_CURRENT);

通知Service

protected void onHandleIntent(Intent intent) {
        int taskId = intent.getIntExtra("id", -1);
        TodoTask task=mTaskDatabase.getTask(taskId);

        if (task==null){return;}

        Notification  notification = new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.icon)
                .setContentTitle(mTaskDatabase.getTask(taskId).getName())
                .setContentText(mTaskDatabase.getTask(taskId).getNote())
                .setDefaults(NotificationCompat.DEFAULT_ALL)
                .setTicker(task.getName())
                .setPriority(NotificationCompat.PRIORITY_MAX)
                .build();

总结

这篇内容主要是2019年的老东西了,这个还是要反思一下当初做的时候为啥没有写文档。现在这篇介绍文档肯定没有当初写的好。
还有就是技术栈的问题,之前的我的东西都是自己搞出来的,我发现这个老外使用了很多开源的东西来帮助自己开发,这些让开发变得方便快捷是我应该学习的。
在前面的人的基础上对代码进行改进或者按照自己需求改动确实也能学到很多东西。


文章作者: Cyber-Peng
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-ND 4.0 许可协议。转载请注明来源 Cyber-Peng !
 上一篇
如何使用git打标签 如何使用git打标签
如何使用git打标签学会使用git之后我就用git来管理我的项目,直到有一天我发现别人的项目里面有很多的标签,就像下面的图上所示。 我也就学习了一下,这里分享一下我的学习成果。 这里我只说最简单的内容,如果有问题请查阅文末的官方文档。 给
2020-03-05
下一篇 
CCF CSP 201312-4 有趣的数 CCF CSP 201312-4 有趣的数
CCF CSP 201312-4 有趣的数问题描述我们把一个数称为有趣的,当且仅当: 它的数字只包含0, 1, 2, 3,且这四个数字都出现过至少一次。 所有的0都出现在所有的1之前,而所有的2都出现在所有的3之前。 最高位数字不为0
2020-02-27
  目录