reader/android: DB interface similar to syncslides.
Change-Id: I0fe2842955d2e1464ecb3146962b25e1c2d18c81
diff --git a/android/app/src/main/java/io/v/android/apps/reader/DB.java b/android/app/src/main/java/io/v/android/apps/reader/DB.java
new file mode 100644
index 0000000..f6fa2a0
--- /dev/null
+++ b/android/app/src/main/java/io/v/android/apps/reader/DB.java
@@ -0,0 +1,88 @@
+// Copyright 2015 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.android.apps.reader;
+
+import android.content.Context;
+
+/**
+ * Borrowed the idea of having a DB interface from syncslides.
+ *
+ * Provides high-level methods for getting and setting the state of PDF reader.
+ * It is an interface instead of a concrete class to make testing easier.
+ */
+public interface DB {
+
+ class Singleton {
+
+ private static volatile DB instance;
+
+ public static DB get(Context context) {
+ DB result = instance;
+ if (instance == null) {
+ synchronized (Singleton.class) {
+ result = instance;
+ if (result == null) {
+ // TODO(youngseokyoon): Replace this with a syncbase DB.
+ instance = result = new FakeDB(context);
+ }
+ }
+ }
+
+ return result;
+ }
+ }
+
+ /**
+ * Represents a PDF file and its metadata.
+ *
+ * TODO(youngseokyoon): update this interface, once the syncbase DB schema is defined.
+ */
+ interface PdfFile {
+ String getName();
+ }
+
+ /**
+ * Callbacks for when the dataset changes dynamically.
+ *
+ * TODO(youngseokyoon): reorganize the interfaces into sub-packages.
+ */
+ interface Listener {
+ void notifyItemChanged(int position);
+ void notifyItemInserted(int position);
+ void notifyItemRemoved(int position);
+ }
+
+ /**
+ * Provides a list of PDF files via an API that fits well with RecyclerView.Adapter.
+ */
+ interface PdfFileList {
+ /**
+ * Returns the number of available PDF files.
+ */
+ int getItemCount();
+
+ /**
+ * Returns the PDF file object at the given position.
+ */
+ PdfFile getPdfFile(int position);
+
+ /**
+ * Sets the listener for changes to the list. There can only be one listener.
+ */
+ void setListener(Listener listener);
+
+ /**
+ * Indicates that the list is no longer needed and should stop notifying its listener.
+ */
+ void discard();
+ }
+
+ /**
+ * Gets the list of available PDF files.
+ * @return a list of PDF files.
+ */
+ PdfFileList getPdfFileList();
+
+}
diff --git a/android/app/src/main/java/io/v/android/apps/reader/FakeDB.java b/android/app/src/main/java/io/v/android/apps/reader/FakeDB.java
new file mode 100644
index 0000000..c78d431
--- /dev/null
+++ b/android/app/src/main/java/io/v/android/apps/reader/FakeDB.java
@@ -0,0 +1,83 @@
+// Copyright 2015 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.android.apps.reader;
+
+import android.content.Context;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A fake implementation of the DB interface for manual testing.
+ */
+public class FakeDB implements DB {
+
+ private static final String[] PDF_FILE_NAMES = {
+ "Foo.pdf",
+ "Bar.pdf"
+ };
+
+ private FakePdfFileList mPdfFileList;
+
+ public FakeDB(Context context) {
+ mPdfFileList = new FakePdfFileList();
+ }
+
+ class FakePdfFile implements DB.PdfFile {
+
+ private String mName;
+
+ public FakePdfFile(String name) {
+ mName = name;
+ }
+
+ @Override
+ public String getName() {
+ return mName;
+ }
+ }
+
+ class FakePdfFileList implements DB.PdfFileList {
+
+ private List<FakePdfFile> mPdfFiles;
+ private Listener mListener;
+
+ public FakePdfFileList() {
+ mPdfFiles = new ArrayList<>();
+ for (String fileName : PDF_FILE_NAMES) {
+ mPdfFiles.add(new FakePdfFile(fileName));
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ return mPdfFiles.size();
+ }
+
+ @Override
+ public FakePdfFile getPdfFile(int position) {
+ return mPdfFiles.get(position);
+ }
+
+ @Override
+ public void setListener(Listener listener) {
+ // This fake list never calls the notify methods.
+ // Just check if the listener is set only once.
+ assert mListener == null;
+ mListener = listener;
+ }
+
+ @Override
+ public void discard() {
+ // Nothing to do.
+ }
+ }
+
+ @Override
+ public PdfFileList getPdfFileList() {
+ return mPdfFileList;
+ }
+
+}
diff --git a/android/app/src/main/java/io/v/android/apps/reader/PdfChooserActivity.java b/android/app/src/main/java/io/v/android/apps/reader/PdfChooserActivity.java
index 4549cc7..580f494 100644
--- a/android/app/src/main/java/io/v/android/apps/reader/PdfChooserActivity.java
+++ b/android/app/src/main/java/io/v/android/apps/reader/PdfChooserActivity.java
@@ -21,22 +21,30 @@
*/
public class PdfChooserActivity extends Activity {
+ private RecyclerView mRecyclerView;
+ private PdfListAdapter mAdapter;
+
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pdf_chooser);
- RecyclerView recyclerView = (RecyclerView) findViewById(R.id.pdf_list);
- recyclerView.setHasFixedSize(true);
+ mRecyclerView = (RecyclerView) findViewById(R.id.pdf_list);
+ mRecyclerView.setHasFixedSize(true);
// Use the linear layout manager for the recycler view
RecyclerView.LayoutManager layoutManager= new LinearLayoutManager(this);
- recyclerView.setLayoutManager(layoutManager);
+ mRecyclerView.setLayoutManager(layoutManager);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
// The adapter for the recycler view
- PdfListAdapter adapter = new PdfListAdapter();
+ mAdapter = new PdfListAdapter(this);
// When a file is clicked from the list, start the PdfViewerActivity.
- adapter.setOnPdfFileClickListener(new PdfListAdapter.OnPdfFileClickListener() {
+ mAdapter.setOnPdfFileClickListener(new PdfListAdapter.OnPdfFileClickListener() {
@Override
public void onPdfFileClick(PdfListAdapter adapter, View v, int position) {
Intent intent = PdfViewerActivity.createIntent(
@@ -46,7 +54,15 @@
}
});
- recyclerView.setAdapter(adapter);
+ mRecyclerView.setAdapter(mAdapter);
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+
+ mAdapter.stop();
+ mAdapter = null;
}
@Override
diff --git a/android/app/src/main/java/io/v/android/apps/reader/PdfListAdapter.java b/android/app/src/main/java/io/v/android/apps/reader/PdfListAdapter.java
index 0a570b6..c134fcf 100644
--- a/android/app/src/main/java/io/v/android/apps/reader/PdfListAdapter.java
+++ b/android/app/src/main/java/io/v/android/apps/reader/PdfListAdapter.java
@@ -4,6 +4,7 @@
package io.v.android.apps.reader;
+import android.content.Context;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
@@ -11,18 +12,17 @@
import android.view.ViewGroup;
import android.widget.TextView;
+import io.v.android.apps.reader.DB.Listener;
+import io.v.android.apps.reader.DB.PdfFileList;
+
/**
* Adapter that binds the list of pdf files to the corresponding card views.
*/
-public class PdfListAdapter extends RecyclerView.Adapter<PdfListAdapter.ViewHolder> {
+public class PdfListAdapter extends RecyclerView.Adapter<PdfListAdapter.ViewHolder>
+ implements Listener {
- private OnPdfFileClickListener mListener;
-
- // TODO(youngseokyoon): Replace this temporary list with real data coming from the syncbase.
- private static final String[] SAMPLE_PDF_LIST = {
- "Foo.pdf",
- "Bar.pdf",
- };
+ private OnPdfFileClickListener mClickListener;
+ private PdfFileList mPdfFileList;
public class ViewHolder extends RecyclerView.ViewHolder {
public CardView mCardView;
@@ -36,16 +36,20 @@
mCardView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- if (mListener != null) {
- mListener.onPdfFileClick(PdfListAdapter.this, v, getPosition());
+ if (mClickListener != null) {
+ mClickListener.onPdfFileClick(PdfListAdapter.this, v, getPosition());
}
}
});
}
}
- public PdfListAdapter() {
- mListener = null;
+ public PdfListAdapter(Context context) {
+ mClickListener = null;
+
+ DB db = DB.Singleton.get(context);
+ mPdfFileList = db.getPdfFileList();
+ mPdfFileList.setListener(this);
}
@Override
@@ -63,16 +67,21 @@
}
public String getItem(int position) {
- return SAMPLE_PDF_LIST[position];
+ return mPdfFileList.getPdfFile(position).getName();
}
@Override
public int getItemCount() {
- return SAMPLE_PDF_LIST.length;
+ return mPdfFileList.getItemCount();
}
- public void setOnPdfFileClickListener(OnPdfFileClickListener listener) {
- mListener = listener;
+ public void setOnPdfFileClickListener(OnPdfFileClickListener clickListener) {
+ mClickListener = clickListener;
+ }
+
+ public void stop() {
+ mPdfFileList.discard();
+ mPdfFileList = null;
}
/**