Skip to content

Commit

Permalink
Build out example-todo
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonwyatt committed Nov 24, 2016
1 parent 213213b commit 167100f
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 21 deletions.
1 change: 1 addition & 0 deletions example-todo/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@ dependencies {
})
compile 'com.android.support:appcompat-v7:25.0.1'
compile 'com.android.support:design:25.0.1'
compile 'com.yarolegovich:lovely-dialog:1.0.4'
testCompile 'junit:junit:4.12'
}
102 changes: 91 additions & 11 deletions example-todo/src/main/java/co/jasonwyatt/squeakytodo/MainActivity.java
Original file line number Diff line number Diff line change
@@ -1,29 +1,34 @@
package co.jasonwyatt.squeakytodo;

import android.os.AsyncTask;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.util.DiffUtil;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.PopupMenu;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.TextView;

import com.yarolegovich.lovelydialog.LovelyTextInputDialog;

import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
import java.util.Observer;

import co.jasonwyatt.squeakytodo.event.DeleteEvent;

public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<List<Todo>>, Observer {

private Adapter mAdapter;
Expand All @@ -50,11 +55,25 @@ protected void onCreate(Bundle savedInstanceState) {
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new LovelyTextInputDialog(view.getContext())
.setConfirmButton(R.string.save, new LovelyTextInputDialog.OnTextInputConfirmListener() {
@Override
public void onTextInputConfirmed(String text) {
sObservable.notifyObservers(new Todo(text.trim()));
}
})
.show();
}
});

RecyclerView rv = (RecyclerView) findViewById(R.id.content_main);
rv.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
mAdapter = new Adapter();
rv.setAdapter(mAdapter);
rv.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
}

@Override
Expand Down Expand Up @@ -86,10 +105,21 @@ public void onLoaderReset(Loader<List<Todo>> loader) {
@Override
public void update(Observable observable, Object o) {
if (o instanceof Todo) {
Todo todo = (Todo) o;
if (todo.getId() >= 0) {
AsyncTask.execute(new Todo.SaveRunnable(App.getInstance().getDB(), todo));
}
new Todo.SaveTask(App.getInstance().getDB(), (Todo) o) {
@Override
protected void onPostExecute(List<Todo> todos) {
mAdapter.setTodoItems(todos);
}
}.execute();
}

if (o instanceof DeleteEvent) {
new Todo.DeleteTask(App.getInstance().getDB(), ((DeleteEvent) o).getItem()) {
@Override
protected void onPostExecute(List<Todo> todos) {
mAdapter.setTodoItems(todos);
}
}.execute();
}
}

Expand All @@ -100,9 +130,47 @@ private static class Adapter extends RecyclerView.Adapter<TodoHolder> {
mTodoItems = new ArrayList<>(0);
}

void setTodoItems(List<Todo> todoItems) {
void setTodoItems(final List<Todo> todoItems) {
DiffUtil.DiffResult res = DiffUtil.calculateDiff(new DiffUtil.Callback() {
@Override
public int getOldListSize() {
return mTodoItems.size();
}

@Override
public int getNewListSize() {
return todoItems.size();
}

@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
return mTodoItems.get(oldItemPosition).getId() == todoItems.get(newItemPosition).getId();
}

@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
Todo oude = mTodoItems.get(oldItemPosition);
Todo nieuw = todoItems.get(newItemPosition);

boolean contentEquals = false;
if (oude.getContent() == null && nieuw.getContent() == null) {
contentEquals = true;
} else if (oude.getContent() != null && nieuw.getContent() != null && oude.getContent().equals(nieuw.getContent())) {
contentEquals = true;
}

boolean finishedEquals = false;
if (oude.getFinishedDate() == null && nieuw.getFinishedDate() == null) {
finishedEquals = true;
} else if (oude.getFinishedDate() != null && nieuw.getFinishedDate() != null && oude.getFinishedDate().equals(nieuw.getFinishedDate())) {
finishedEquals = true;
}

return contentEquals && finishedEquals;
}
});
mTodoItems = todoItems;
notifyDataSetChanged();
res.dispatchUpdatesTo(this);
}

@Override
Expand Down Expand Up @@ -153,7 +221,19 @@ public void onClick(View view) {

@Override
public boolean onLongClick(View view) {
return false;
PopupMenu menu = new PopupMenu(view.getContext(), view);
menu.inflate(R.menu.item_popup);
menu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
if (item.getItemId() == R.id.delete) {
sObservable.notifyObservers(new DeleteEvent(mItem));
}
return false;
}
});
menu.show();
return true;
}

@Override
Expand Down
56 changes: 47 additions & 9 deletions example-todo/src/main/java/co/jasonwyatt/squeakytodo/Todo.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

import android.content.Context;
import android.database.Cursor;
import android.os.AsyncTask;
import android.support.annotation.WorkerThread;
import android.support.v4.content.AsyncTaskLoader;
import android.support.v4.content.Loader;

import java.util.LinkedList;
import java.util.List;
Expand All @@ -28,6 +28,13 @@ public Todo(int id, long createDate, String content, Long finishedDate) {
mFinishedDate = finishedDate;
}

public Todo(String s) {
mId = -1;
mCreateDate = System.currentTimeMillis();
mContent = s;
mFinishedDate = null;
}

public int getId() {
return mId;
}
Expand All @@ -48,16 +55,22 @@ public void setFinishedDate(Long date) {
mFinishedDate = date;
}

@SuppressWarnings("WeakerAccess")
@WorkerThread
public static void saveTodo(Database db, Todo todo) {
db.update("UPDATE todos SET create_date = ?, content = ?, finished_date = ? WHERE rowid = ?", todo.getCreateDate(), todo.getContent(), todo.getFinishedDate(), todo.getId());
if (todo.getId() >= 0) {
db.update("UPDATE todos SET create_date = ?, content = ?, finished_date = ? WHERE rowid = ?", todo.getCreateDate(), todo.getContent(), todo.getFinishedDate(), todo.getId());
} else {
db.insert("INSERT INTO todos (create_date, content) VALUES (?, ?)", todo.getCreateDate(), todo.getContent());
}
}

@SuppressWarnings("WeakerAccess")
@WorkerThread
public static List<Todo> getTodos(Database db) {
List<Todo> todos = new LinkedList<>();

Cursor c = db.query("SELECT rowid, create_date, content, finished_date FROM todos ORDER BY finished_date ASC, create_date ASC");
Cursor c = db.query("SELECT rowid, create_date, content, finished_date, case when finished_date IS NULL then 0 else 1 end AS is_finished FROM todos ORDER BY is_finished ASC, finished_date DESC, create_date ASC");
try {
while (c.moveToNext()) {
todos.add(new Todo(c.getInt(0), c.getLong(1), c.getString(2), c.isNull(3) ? null : c.getLong(3)));
Expand All @@ -69,22 +82,47 @@ public static List<Todo> getTodos(Database db) {
return todos;
}

public static class SaveRunnable implements Runnable {
@SuppressWarnings("WeakerAccess")
@WorkerThread
public static void deleteTodo(Database db, Todo todo) {
if (todo.getId() >= 0) {
db.update("DELETE FROM todos WHERE rowid = ?", todo.getId());
}
}

static class SaveTask extends AsyncTask<Void, Void, List<Todo>> {
private final Database mDB;
private final Todo mTodo;

public SaveRunnable(Database db, Todo todo) {
SaveTask(Database db, Todo todo) {
mDB = db;
mTodo = todo;
}

@Override
public void run() {
protected List<Todo> doInBackground(Void... voids) {
saveTodo(mDB, mTodo);
return getTodos(mDB);
}
}

static class DeleteTask extends AsyncTask<Void, Void, List<Todo>> {
private final Database mDB;
private final Todo mTodo;

DeleteTask(Database db, Todo todo) {
mDB = db;
mTodo = todo;
}

@Override
protected List<Todo> doInBackground(Void... voids) {
deleteTodo(mDB, mTodo);
return getTodos(mDB);
}
}

public static class Table extends co.jasonwyatt.squeaky.Table {
static class Table extends co.jasonwyatt.squeaky.Table {
private static final String NAME = "todos";

@Override
Expand Down Expand Up @@ -115,8 +153,8 @@ public String[] getMigration(int nextVersion) {
}
}

public static class Loader extends AsyncTaskLoader<List<Todo>> {
public Loader(Context context) {
static class Loader extends AsyncTaskLoader<List<Todo>> {
Loader(Context context) {
super(context);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package co.jasonwyatt.squeakytodo.event;

import co.jasonwyatt.squeakytodo.Todo;

/**
* @author jason
*/
public class DeleteEvent {
private final Todo mItem;

public DeleteEvent(Todo item) {
mItem = item;
}

public Todo getItem() {
return mItem;
}
}
2 changes: 1 addition & 1 deletion example-todo/src/main/res/layout/todo_item.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:padding="16dp"
android:gravity="center_vertical|start"
tools:context=".MainActivity"
android:background="?selectableItemBackground"
Expand Down
4 changes: 4 additions & 0 deletions example-todo/src/main/res/menu/item_popup.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/delete" android:title="@string/delete" />
</menu>
2 changes: 2 additions & 0 deletions example-todo/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<resources>
<string name="app_name">Squeaky ToDo</string>
<string name="action_settings">Settings</string>
<string name="save">Save</string>
<string name="delete">Delete</string>
</resources>

0 comments on commit 167100f

Please sign in to comment.