java/projects/todos: Allow Screen Rotation. Use Cards

Initializing Firebase only once (Singleton) to allow for screen
rotation to succeed.

Use Cards to show TodoLists and Tasks.

Change-Id: I8221d8bb1a6dd6ea3e3adc1ded25ca8dbc7ccccc
diff --git a/projects/todos/app/build.gradle b/projects/todos/app/build.gradle
index 698c363..3f6b1a5 100644
--- a/projects/todos/app/build.gradle
+++ b/projects/todos/app/build.gradle
@@ -29,6 +29,7 @@
     testCompile 'junit:junit:4.12'
     compile 'com.android.support:appcompat-v7:23.1.1'
     compile 'com.android.support:design:23.1.1'
-    compile 'com.firebase:firebase-client-android:2.5.2+'
-    compile 'com.android.support:recyclerview-v7:+'
+    compile 'com.firebase:firebase-client-android:2.5.2'
+    compile 'com.android.support:cardview-v7:23.1.1'
+    compile 'com.android.support:recyclerview-v7:23.1.1'
 }
diff --git a/projects/todos/app/src/main/AndroidManifest.xml b/projects/todos/app/src/main/AndroidManifest.xml
index 89aa1a7..6bb5351 100644
--- a/projects/todos/app/src/main/AndroidManifest.xml
+++ b/projects/todos/app/src/main/AndroidManifest.xml
@@ -12,7 +12,6 @@
         android:theme="@style/AppTheme">
         <activity
             android:name="io.v.todos.MainActivity"
-            android:screenOrientation="portrait"
             android:label="@string/app_name"
             android:theme="@style/AppTheme.NoActionBar">
             <intent-filter>
@@ -23,7 +22,6 @@
         </activity>
         <activity
             android:name="io.v.todos.TodoListActivity"
-            android:screenOrientation="portrait"
             android:label="@string/app_name"
             android:theme="@style/AppTheme.NoActionBar">
         </activity>
diff --git a/projects/todos/app/src/main/java/io/v/todos/FirebaseSingleton.java b/projects/todos/app/src/main/java/io/v/todos/FirebaseSingleton.java
new file mode 100644
index 0000000..0efd48c
--- /dev/null
+++ b/projects/todos/app/src/main/java/io/v/todos/FirebaseSingleton.java
@@ -0,0 +1,38 @@
+// Copyright 2016 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package io.v.todos;
+
+import android.content.Context;
+
+import com.firebase.client.Firebase;
+
+/**
+ * TODO(alexfandrianto): We may want to shove a lot more into this singleton and have it subclass
+ * a common interface with Syncbase. I want this to also manage data watches and changes.
+ *
+ * @author alexfandrianto
+ */
+public class FirebaseSingleton {
+    private FirebaseSingleton() {} // Marked private to prevent accidental instantiation.
+
+    private static FirebaseSingleton singleton;
+
+    /**
+     * Obtain a database singleton that can be used to manipulate data.
+     *
+     * @param context An Android context, usually from an Android activity or application.
+     * @return
+     */
+    public synchronized static FirebaseSingleton getDatabase(Context context) {
+        if (singleton == null) {
+            singleton = new FirebaseSingleton();
+
+            // Set up Firebase with the context and have it persist data locally even when offline.
+            Firebase.setAndroidContext(context);
+            Firebase.getDefaultConfig().setPersistenceEnabled(true);
+        }
+        return singleton;
+    }
+}
diff --git a/projects/todos/app/src/main/java/io/v/todos/MainActivity.java b/projects/todos/app/src/main/java/io/v/todos/MainActivity.java
index ed74697..da7119f 100644
--- a/projects/todos/app/src/main/java/io/v/todos/MainActivity.java
+++ b/projects/todos/app/src/main/java/io/v/todos/MainActivity.java
@@ -164,11 +164,8 @@
             }
         }).attachToRecyclerView(recyclerView);
 
-        // Set up Firebase with the context and tell it to persist data locally even if we're offline.
-        Firebase.setAndroidContext(this);
-        Firebase.getDefaultConfig().setPersistenceEnabled(true);
-
         // Prepare our Firebase Reference and the primary listener (SNACKOOS).
+        FirebaseSingleton.getDatabase(this);
         myFirebaseRef = new Firebase(FIREBASE_EXAMPLE_URL);
         setUpSnackoos();
     }
diff --git a/projects/todos/app/src/main/java/io/v/todos/TaskRecyclerAdapter.java b/projects/todos/app/src/main/java/io/v/todos/TaskRecyclerAdapter.java
index e4caae3..91ff8cc 100644
--- a/projects/todos/app/src/main/java/io/v/todos/TaskRecyclerAdapter.java
+++ b/projects/todos/app/src/main/java/io/v/todos/TaskRecyclerAdapter.java
@@ -51,7 +51,7 @@
                 return i;
             }
         }
-        return 0;
+        return backup.size();
     }
 
     public void setShowDone(boolean showDone) {
diff --git a/projects/todos/app/src/main/java/io/v/todos/TaskViewHolder.java b/projects/todos/app/src/main/java/io/v/todos/TaskViewHolder.java
index d07079c..632441f 100644
--- a/projects/todos/app/src/main/java/io/v/todos/TaskViewHolder.java
+++ b/projects/todos/app/src/main/java/io/v/todos/TaskViewHolder.java
@@ -4,6 +4,7 @@
 
 package io.v.todos;
 
+import android.support.v7.widget.CardView;
 import android.support.v7.widget.RecyclerView;
 import android.view.View;
 import android.widget.ImageView;
@@ -13,13 +14,13 @@
  * @author alexfandrianto
  */
 public class TaskViewHolder extends RecyclerView.ViewHolder{
-    private View myView;
+    private CardView myView;
     private boolean showDone = true;
 
     public TaskViewHolder(View itemView) {
         super(itemView);
 
-        myView = itemView;
+        myView = (CardView)itemView;
     }
 
     public void bindTask(Task task, View.OnClickListener listener) {
@@ -34,7 +35,7 @@
         final TextView created=(TextView)myView.findViewById(R.id.task_time);
         created.setText(computeCreated(task));
 
-        myView.setBackgroundColor(task.getDone() ? 0xFFCCCCCC : 0xFFFFFFFF);
+        myView.setCardBackgroundColor(task.getDone() ? 0xFFCCCCCC : 0xFFFFFFFF);
 
         myView.setTag(task.getKey());
         myView.setOnClickListener(listener);
diff --git a/projects/todos/app/src/main/java/io/v/todos/TodoListActivity.java b/projects/todos/app/src/main/java/io/v/todos/TodoListActivity.java
index 4bea69f..c9a0a3c 100644
--- a/projects/todos/app/src/main/java/io/v/todos/TodoListActivity.java
+++ b/projects/todos/app/src/main/java/io/v/todos/TodoListActivity.java
@@ -163,11 +163,8 @@
             }
         }).attachToRecyclerView(recyclerView);
 
-        // Set up Firebase with the context and tell it to persist data locally even if we're offline.
-        Firebase.setAndroidContext(this);
-        //Firebase.getDefaultConfig().setPersistenceEnabled(true);
-
         // Prepare our Firebase Reference and the primary listener (SNACKOOS).
+        FirebaseSingleton.getDatabase(this);
         myFirebaseRef = new Firebase(MainActivity.FIREBASE_EXAMPLE_URL);
         setUpSnackoo();
         setUpSnackoos();
diff --git a/projects/todos/app/src/main/java/io/v/todos/TodoListViewHolder.java b/projects/todos/app/src/main/java/io/v/todos/TodoListViewHolder.java
index 82b97a1..f0d36c4 100644
--- a/projects/todos/app/src/main/java/io/v/todos/TodoListViewHolder.java
+++ b/projects/todos/app/src/main/java/io/v/todos/TodoListViewHolder.java
@@ -4,6 +4,7 @@
 
 package io.v.todos;
 
+import android.support.v7.widget.CardView;
 import android.support.v7.widget.RecyclerView;
 import android.view.View;
 import android.widget.TextView;
@@ -12,12 +13,12 @@
  * @author alexfandrianto
  */
 public class TodoListViewHolder extends RecyclerView.ViewHolder {
-    private View myView;
+    private CardView myView;
 
     public TodoListViewHolder(View itemView) {
         super(itemView);
 
-        myView = itemView;
+        myView = (CardView)itemView;
     }
 
     public void bindTodoList(TodoList todoList, View.OnClickListener listener) {
@@ -32,7 +33,7 @@
         final TextView timeAgo=(TextView)myView.findViewById(R.id.todo_list_time);
         timeAgo.setText(computeTimeAgo(todoList));
 
-        myView.setBackgroundColor(todoList.getDone() ? 0xFFCCCCCC : 0xFFFFFFFF);
+        myView.setCardBackgroundColor(todoList.getDone() ? 0xFFCCCCCC : 0xFFFFFFFF);
 
         myView.setTag(todoList.getKey());
         myView.setOnClickListener(listener);
diff --git a/projects/todos/app/src/main/res/layout/task_row.xml b/projects/todos/app/src/main/res/layout/task_row.xml
index a06e741..8fedb85 100644
--- a/projects/todos/app/src/main/res/layout/task_row.xml
+++ b/projects/todos/app/src/main/res/layout/task_row.xml
@@ -1,18 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/root"
+<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    xmlns:card_view="http://schemas.android.com/apk/res-auto"
+    android:layout_marginBottom="1dp"
+    card_view:cardElevation="1dp"
+    card_view:cardBackgroundColor="#DDDDFF"
+    card_view:cardCornerRadius="5dp">
 
     <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:orientation="horizontal"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:id="@+id/row">
+        android:layout_height="wrap_content">
 
         <ImageView android:id="@+id/task_done"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:layout_weight = "0"
             android:src="@android:drawable/checkbox_on_background"
             android:layout_gravity="center_vertical"
             android:layout_margin="@dimen/fab_margin"
@@ -29,26 +33,19 @@
                 android:layout_height="wrap_content"
                 android:layout_weight = "1"
                 android:gravity="center_vertical"
-                android:layout_alignParentTop="true"
-                android:layout_alignParentBottom="true"
                 android:textStyle="bold"
                 android:textSize="22sp"
                 android:textColor="#000000"
-                android:layout_marginTop="5dp"
-                android:layout_marginBottom="5dp" />
+                android:layout_margin="5dp"  />
 
             <TextView android:id="@+id/task_time"
                 android:layout_width="fill_parent"
                 android:layout_height="wrap_content"
                 android:layout_weight = "1"
                 android:gravity="center_vertical"
-                android:layout_alignParentTop="true"
-                android:layout_alignParentBottom="true"
-                android:textStyle="bold"
-                android:textSize="22sp"
-                android:textColor="#000000"
-                android:layout_marginTop="5dp"
-                android:layout_marginBottom="5dp" />
+                android:textSize="12sp"
+                android:textColor="#333333"
+                android:layout_margin="5dp" />
         </LinearLayout>
     </LinearLayout>
-</RelativeLayout>
\ No newline at end of file
+</android.support.v7.widget.CardView>
\ No newline at end of file
diff --git a/projects/todos/app/src/main/res/layout/todo_list_row.xml b/projects/todos/app/src/main/res/layout/todo_list_row.xml
index 04a4082..f69ddfb 100644
--- a/projects/todos/app/src/main/res/layout/todo_list_row.xml
+++ b/projects/todos/app/src/main/res/layout/todo_list_row.xml
@@ -1,65 +1,51 @@
 <?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/root"
+<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    xmlns:card_view="http://schemas.android.com/apk/res-auto"
+    android:layout_marginBottom="1dp"
+    card_view:cardElevation="1dp"
+    card_view:cardBackgroundColor="#DDDDFF"
+    card_view:cardCornerRadius="5dp">
 
     <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-        android:orientation="horizontal"
+        android:orientation="vertical"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:id="@+id/row">
+        android:layout_height="wrap_content">
+
+        <TextView android:id="@+id/todo_list_name"
+            android:layout_width="fill_parent"
+            android:layout_weight = "1"
+            android:layout_height="wrap_content"
+            android:gravity="center_vertical"
+            android:textStyle="bold"
+            android:textSize="22sp"
+            android:textColor="#000000"
+            android:layout_margin="5dp" />
 
         <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-            android:orientation="vertical"
+            android:orientation="horizontal"
             android:layout_width="match_parent"
-            android:layout_height="wrap_content">
+            android:layout_height="wrap_content"
+            android:layout_weight = "1">
 
-            <TextView android:id="@+id/todo_list_name"
-                android:layout_width="fill_parent"
+            <TextView android:id="@+id/todo_list_completed"
+                android:layout_width="wrap_content"
                 android:layout_weight = "1"
-                android:layout_height="wrap_content"
+                android:layout_height="fill_parent"
                 android:gravity="center_vertical"
-                android:layout_alignParentTop="true"
-                android:layout_alignParentBottom="true"
-                android:textStyle="bold"
-                android:textSize="22dp"
-                android:textColor="#000000"
-                android:layout_marginTop="5dp"
-                android:layout_marginBottom="5dp" />
+                android:textSize="12sp"
+                android:textColor="#333333"
+                android:layout_margin="5dp" />
 
-            <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-                android:orientation="horizontal"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_weight = "1">
-
-                <TextView android:id="@+id/todo_list_completed"
-                    android:layout_width="wrap_content"
-                    android:layout_weight = "1"
-                    android:layout_height="fill_parent"
-                    android:gravity="center_vertical"
-                    android:layout_alignParentTop="true"
-                    android:layout_alignParentBottom="true"
-                    android:textStyle="bold"
-                    android:textSize="22dp"
-                    android:textColor="#000000"
-                    android:layout_marginTop="5dp"
-                    android:layout_marginBottom="5dp" />
-
-                <TextView android:id="@+id/todo_list_time"
-                    android:layout_width="wrap_content"
-                    android:layout_weight = "1"
-                    android:layout_height="fill_parent"
-                    android:gravity="center_vertical"
-                    android:layout_alignParentTop="true"
-                    android:layout_alignParentBottom="true"
-                    android:textStyle="bold"
-                    android:textSize="22dp"
-                    android:textColor="#000000"
-                    android:layout_marginTop="5dp"
-                    android:layout_marginBottom="5dp" />
-            </LinearLayout>
+            <TextView android:id="@+id/todo_list_time"
+                android:layout_width="wrap_content"
+                android:layout_weight = "1"
+                android:layout_height="fill_parent"
+                android:gravity="center_vertical"
+                android:textSize="12sp"
+                android:textColor="#333333"
+                android:layout_margin="5dp" />
         </LinearLayout>
     </LinearLayout>
-</RelativeLayout>
\ No newline at end of file
+</android.support.v7.widget.CardView>
\ No newline at end of file