diff --git a/app/src/main/java/org/bspeice/minimalbible/activity/BaseNavigationDrawerFragment.java b/app/src/main/java/org/bspeice/minimalbible/activity/BaseNavigationDrawerFragment.java
deleted file mode 100644
index b0f0e19..0000000
--- a/app/src/main/java/org/bspeice/minimalbible/activity/BaseNavigationDrawerFragment.java
+++ /dev/null
@@ -1,301 +0,0 @@
-package org.bspeice.minimalbible.activity;
-
-import android.app.Activity;
-import android.content.SharedPreferences;
-import android.content.res.Configuration;
-import android.os.Build;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-import android.support.v4.app.ActionBarDrawerToggle;
-import android.support.v4.app.Fragment;
-import android.support.v4.view.GravityCompat;
-import android.support.v4.widget.DrawerLayout;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.ActionBarActivity;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.ExpandableListView;
-import android.widget.ListView;
-
-import com.readystatesoftware.systembartint.SystemBarTintManager;
-
-import org.bspeice.minimalbible.R;
-
-/**
- * Fragment used for managing interactions for and presentation of a navigation
- * drawer. See the design guidelines for a complete explanation of the behaviors
- * implemented here.
- * TODO: Refactor to allow ExpandableListView
- */
-public class BaseNavigationDrawerFragment extends Fragment {
-
- /**
- * Remember the position of the selected item.
- */
- private static final String STATE_SELECTED_POSITION = "selected_navigation_drawer_position";
-
- /**
- * Per the design guidelines, you should show the drawer on launch until the
- * user manually expands it. This shared preference tracks this.
- */
- private static final String PREF_USER_LEARNED_DRAWER = "navigation_drawer_learned";
- protected ListView mDrawerListView;
- protected int mCurrentSelectedPosition = 0;
- /**
- * A pointer to the current callbacks instance (the Activity).
- */
- private NavigationDrawerCallbacks mCallbacks;
- /**
- * Helper component that ties the action bar to the navigation drawer.
- */
- private ActionBarDrawerToggle mDrawerToggle;
- private DrawerLayout mDrawerLayout;
- private View mFragmentContainerView;
- private boolean mFromSavedInstanceState;
- private boolean mUserLearnedDrawer;
-
- public BaseNavigationDrawerFragment() {
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- // Read in the flag indicating whether or not the user has demonstrated
- // awareness of the
- // drawer. See PREF_USER_LEARNED_DRAWER for details.
- SharedPreferences sp = PreferenceManager
- .getDefaultSharedPreferences(getActivity());
- mUserLearnedDrawer = sp.getBoolean(PREF_USER_LEARNED_DRAWER, false);
-
- if (savedInstanceState != null) {
- mCurrentSelectedPosition = savedInstanceState
- .getInt(STATE_SELECTED_POSITION);
- mFromSavedInstanceState = true;
- }
-
- // Select either the default item (0) or the last selected item.
- selectItem(mCurrentSelectedPosition);
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- // Indicate that this fragment would like to influence the set of
- // actions in the action bar.
- setHasOptionsMenu(true);
- }
-
- public boolean isDrawerOpen() {
- return mDrawerLayout != null
- && mDrawerLayout.isDrawerOpen(mFragmentContainerView);
- }
-
- /**
- * Users of this fragment must call this method to set up the navigation
- * drawer interactions.
- *
- * @param fragmentId
- * The android:id of this fragment in its activity's layout.
- * @param drawerLayout
- * The DrawerLayout containing this fragment's UI.
- */
- public void setUp(int fragmentId, DrawerLayout drawerLayout) {
- mFragmentContainerView = getActivity().findViewById(fragmentId);
- mDrawerLayout = drawerLayout;
-
- // set a custom shadow that overlays the main content when the drawer
- // opens
- mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow,
- GravityCompat.START);
- // set up the drawer's list view with items and click listener
-
- ActionBar actionBar = getActionBar();
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setHomeButtonEnabled(true);
-
- // ActionBarDrawerToggle ties together the the proper interactions
- // between the navigation drawer and the action bar app icon.
- mDrawerToggle = new ActionBarDrawerToggle(getActivity(), /* host Activity */
- mDrawerLayout, /* DrawerLayout object */
- R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */
- R.string.navigation_drawer_open, /*
- * "open drawer" description for
- * accessibility
- */
- R.string.navigation_drawer_close /*
- * "close drawer" description for
- * accessibility
- */
- ) {
- @Override
- public void onDrawerClosed(View drawerView) {
- super.onDrawerClosed(drawerView);
- if (!isAdded()) {
- return;
- }
-
- getActivity().supportInvalidateOptionsMenu(); // calls
- // onPrepareOptionsMenu()
- }
-
- @Override
- public void onDrawerOpened(View drawerView) {
- super.onDrawerOpened(drawerView);
- if (!isAdded()) {
- return;
- }
-
- if (!mUserLearnedDrawer) {
- // The user manually opened the drawer; store this flag to
- // prevent auto-showing
- // the navigation drawer automatically in the future.
- mUserLearnedDrawer = true;
- SharedPreferences sp = PreferenceManager
- .getDefaultSharedPreferences(getActivity());
- sp.edit().putBoolean(PREF_USER_LEARNED_DRAWER, true)
- .commit();
- }
-
- getActivity().supportInvalidateOptionsMenu(); // calls
- // onPrepareOptionsMenu()
- }
- };
-
- // If the user hasn't 'learned' about the drawer, open it to introduce
- // them to the drawer,
- // per the navigation drawer design guidelines.
- if (!mUserLearnedDrawer && !mFromSavedInstanceState) {
- mDrawerLayout.openDrawer(mFragmentContainerView);
- }
-
- // Defer code dependent on restoration of previous instance state.
- mDrawerLayout.post(new Runnable() {
- @Override
- public void run() {
- mDrawerToggle.syncState();
- }
- });
-
- mDrawerLayout.setDrawerListener(mDrawerToggle);
- }
-
- public void selectItem(int position) {
- mCurrentSelectedPosition = position;
- if (mDrawerListView != null) {
- mDrawerListView.setItemChecked(position, true);
- ((NavDrawerAdapter)mDrawerListView.getAdapter()).setCurrentlyHighlighted(position);
- }
- if (mDrawerLayout != null) {
- mDrawerLayout.closeDrawer(mFragmentContainerView);
- }
- if (mCallbacks != null) {
- mCallbacks.onNavigationDrawerItemSelected(position);
- }
- }
-
- @Override
- public void onAttach(Activity activity) {
- super.onAttach(activity);
- try {
- mCallbacks = (NavigationDrawerCallbacks) activity;
- } catch (ClassCastException e) {
- throw new ClassCastException(
- "Activity must implement NavigationDrawerCallbacks.");
- }
- }
-
- @Override
- public void onDetach() {
- super.onDetach();
- mCallbacks = null;
- }
-
- @Override
- public void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- outState.putInt(STATE_SELECTED_POSITION, mCurrentSelectedPosition);
- }
-
- @Override
- public void onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
- // Forward the new configuration the drawer toggle component.
- mDrawerToggle.onConfigurationChanged(newConfig);
- }
-
- @Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
- // If the drawer is open, show the global app actions in the action bar.
- // See also
- // showGlobalContextActionBar, which controls the top-left area of the
- // action bar.
- if (mDrawerLayout != null && isDrawerOpen()) {
- inflater.inflate(R.menu.global, menu);
- showGlobalContextActionBar();
- }
- super.onCreateOptionsMenu(menu, inflater);
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- if (mDrawerToggle.onOptionsItemSelected(item)) {
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
-
- /**
- * Per the navigation drawer design guidelines, updates the action bar to
- * show the global app 'context', rather than just what's in the current
- * screen.
- */
- private void showGlobalContextActionBar() {
- ActionBar actionBar = getActionBar();
- actionBar.setDisplayShowTitleEnabled(true);
- actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
- // actionBar.setTitle(R.string.app_name);
- }
-
- protected ActionBar getActionBar() {
- return ((ActionBarActivity) getActivity()).getSupportActionBar();
- }
-
- public void setInsets(View view) {
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT)
- return;
- SystemBarTintManager tintManager = new SystemBarTintManager(getActivity());
- SystemBarTintManager.SystemBarConfig config = tintManager.getConfig();
- view.setPadding(0, config.getPixelInsetTop(true),
- config.getPixelInsetRight(), config.getPixelInsetBottom());
- }
-
- @Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
-
- // This could also be a ScrollView
- ExpandableListView list = (ExpandableListView) view.findViewById(R.id.list_nav_drawer);
- // This could also be set in your layout, allows the list items to
- // scroll through the bottom padded area (navigation bar)
- list.setClipToPadding(false);
- // Sets the padding to the insets (include action bar and navigation bar
- // padding for the current device and orientation)
- setInsets(list);
- }
-
- /**
- * Callbacks interface that all activities using this fragment must
- * implement.
- */
- public static interface NavigationDrawerCallbacks {
- /**
- * Called when an item in the navigation drawer is selected.
- */
- void onNavigationDrawerItemSelected(int position);
- }
-}
diff --git a/app/src/main/java/org/bspeice/minimalbible/activity/downloader/DownloadActivity.java b/app/src/main/java/org/bspeice/minimalbible/activity/downloader/DownloadActivity.java
index ad55c73..b3dfa23 100644
--- a/app/src/main/java/org/bspeice/minimalbible/activity/downloader/DownloadActivity.java
+++ b/app/src/main/java/org/bspeice/minimalbible/activity/downloader/DownloadActivity.java
@@ -13,7 +13,7 @@ import org.bspeice.minimalbible.MinimalBible;
import org.bspeice.minimalbible.OGHolder;
import org.bspeice.minimalbible.R;
import org.bspeice.minimalbible.activity.BaseActivity;
-import org.bspeice.minimalbible.activity.BaseNavigationDrawerFragment;
+import org.bspeice.minimalbible.activity.navigation.NavDrawerFragment;
import org.crosswire.jsword.book.BookCategory;
import java.util.List;
@@ -24,26 +24,23 @@ import javax.inject.Named;
import dagger.ObjectGraph;
public class DownloadActivity extends BaseActivity implements
- BaseNavigationDrawerFragment.NavigationDrawerCallbacks,
+ NavDrawerFragment.NavigationDrawerCallbacks,
Injector {
private final String TAG = "DownloadActivity";
-
- /**
- * Fragment managing the behaviors, interactions and presentation of the
- * navigation drawer.
- */
- private DownloadNavDrawerFragment mNavigationDrawerFragment;
-
- /**
- * Used to store the last screen title. For use in
- * {@link #restoreActionBar()}.
- */
- private CharSequence mTitle;
-
- @Inject @Named("ValidCategories")
+ @Inject
+ @Named("ValidCategories")
List validCategories;
-
+ /**
+ * Fragment managing the behaviors, interactions and presentation of the
+ * navigation drawer.
+ */
+ private DownloadNavDrawerFragment mNavigationDrawerFragment;
+ /**
+ * Used to store the last screen title. For use in
+ * {@link #restoreActionBar()}.
+ */
+ private CharSequence mTitle;
private ObjectGraph daObjectGraph;
/**
@@ -71,68 +68,68 @@ public class DownloadActivity extends BaseActivity implements
daObjectGraph.inject(o);
}
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
inject(this);
- setContentView(R.layout.activity_download);
+ setContentView(R.layout.activity_download);
- mNavigationDrawerFragment = (DownloadNavDrawerFragment) getSupportFragmentManager()
- .findFragmentById(R.id.navigation_drawer);
- mTitle = getTitle();
+ mNavigationDrawerFragment = (DownloadNavDrawerFragment) getSupportFragmentManager()
+ .findFragmentById(R.id.navigation_drawer);
+ mTitle = getTitle();
- // Set up the drawer.
- mNavigationDrawerFragment.setUp(R.id.navigation_drawer,
- (DrawerLayout) findViewById(R.id.drawer_layout));
- }
+ // Set up the drawer.
+ mNavigationDrawerFragment.setUp(R.id.navigation_drawer,
+ (DrawerLayout) findViewById(R.id.drawer_layout));
+ }
- @Override
- public void onNavigationDrawerItemSelected(int position) {
- // update the main content by replacing fragments
+ @Override
+ public void onNavigationDrawerItemSelected(int position) {
+ // update the main content by replacing fragments
//TODO: Switch to AutoFactory pattern, rather than newInstance()
- FragmentManager fragmentManager = getSupportFragmentManager();
- fragmentManager
- .beginTransaction()
- .replace(R.id.container,
- BookListFragment.newInstance(validCategories.get(position))).commit();
- }
+ FragmentManager fragmentManager = getSupportFragmentManager();
+ fragmentManager
+ .beginTransaction()
+ .replace(R.id.container,
+ BookListFragment.newInstance(validCategories.get(position))).commit();
+ }
- public void onSectionAttached(String category) {
- mTitle = category;
- }
+ public void onSectionAttached(String category) {
+ mTitle = category;
+ }
- public void restoreActionBar() {
- ActionBar actionBar = getSupportActionBar();
- actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
- actionBar.setDisplayShowTitleEnabled(true);
- actionBar.setTitle(mTitle);
- }
+ public void restoreActionBar() {
+ ActionBar actionBar = getSupportActionBar();
+ actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
+ actionBar.setDisplayShowTitleEnabled(true);
+ actionBar.setTitle(mTitle);
+ }
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- if (!mNavigationDrawerFragment.isDrawerOpen()) {
- // Only show items in the action bar relevant to this screen
- // if the drawer is not showing. Otherwise, let the drawer
- // decide what to show in the action bar.
- getMenuInflater().inflate(R.menu.download, menu);
- restoreActionBar();
- return true;
- }
- return super.onCreateOptionsMenu(menu);
- }
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ if (!mNavigationDrawerFragment.isDrawerOpen()) {
+ // Only show items in the action bar relevant to this screen
+ // if the drawer is not showing. Otherwise, let the drawer
+ // decide what to show in the action bar.
+ getMenuInflater().inflate(R.menu.download, menu);
+ restoreActionBar();
+ return true;
+ }
+ return super.onCreateOptionsMenu(menu);
+ }
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- // Handle action bar item clicks here. The action bar will
- // automatically handle clicks on the Home/Up button, so long
- // as you specify a parent activity in AndroidManifest.xml.
- int id = item.getItemId();
- if (id == R.id.action_settings) {
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ // Handle action bar item clicks here. The action bar will
+ // automatically handle clicks on the Home/Up button, so long
+ // as you specify a parent activity in AndroidManifest.xml.
+ int id = item.getItemId();
+ if (id == R.id.action_settings) {
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
}
diff --git a/app/src/main/java/org/bspeice/minimalbible/activity/downloader/DownloadNavDrawerFragment.java b/app/src/main/java/org/bspeice/minimalbible/activity/downloader/DownloadNavDrawerFragment.java
index b96a295..e9171f0 100644
--- a/app/src/main/java/org/bspeice/minimalbible/activity/downloader/DownloadNavDrawerFragment.java
+++ b/app/src/main/java/org/bspeice/minimalbible/activity/downloader/DownloadNavDrawerFragment.java
@@ -1,18 +1,16 @@
package org.bspeice.minimalbible.activity.downloader;
import android.os.Bundle;
-import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
import android.widget.ListView;
import org.bspeice.minimalbible.Injector;
import org.bspeice.minimalbible.R;
-import org.bspeice.minimalbible.activity.BaseNavigationDrawerFragment;
-import org.bspeice.minimalbible.activity.NavDrawerAdapter;
+import org.bspeice.minimalbible.activity.navigation.ListNavAdapter;
+import org.bspeice.minimalbible.activity.navigation.NavDrawerFragment;
import org.crosswire.jsword.book.BookCategory;
import java.util.List;
@@ -20,31 +18,32 @@ import java.util.List;
import javax.inject.Inject;
import javax.inject.Named;
-public class DownloadNavDrawerFragment extends BaseNavigationDrawerFragment {
+public class DownloadNavDrawerFragment extends NavDrawerFragment {
- @Inject @Named("ValidCategories")
+ @Inject
+ @Named("ValidCategories")
List validCategories;
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- ((Injector)getActivity()).inject(this);
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ ((Injector) getActivity()).inject(this);
- mDrawerListView = (ListView) inflater.inflate(
- R.layout.fragment_navigation_drawer, container, false);
- mDrawerListView
- .setOnItemClickListener(new AdapterView.OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView> parent, View view,
- int position, long id) {
- selectItem(position);
- }
- });
+ mDrawerListView = (ListView) inflater.inflate(
+ R.layout.fragment_navigation_drawer, container, false);
+ mDrawerListView
+ .setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view,
+ int position, long id) {
+ selectItem(position);
+ }
+ });
- mDrawerListView.setAdapter(new NavDrawerAdapter(getActivity(),
+ mDrawerListView.setAdapter(new ListNavAdapter(getActivity(),
validCategories));
- mDrawerListView.setItemChecked(mCurrentSelectedPosition, true);
- return mDrawerListView;
- }
+ mDrawerListView.setItemChecked(mCurrentSelectedPosition, true);
+ return mDrawerListView;
+ }
}
diff --git a/app/src/main/java/org/bspeice/minimalbible/activity/viewer/BibleNavAdapter.java b/app/src/main/java/org/bspeice/minimalbible/activity/navigation/ExpListNavAdapter.java
similarity index 63%
rename from app/src/main/java/org/bspeice/minimalbible/activity/viewer/BibleNavAdapter.java
rename to app/src/main/java/org/bspeice/minimalbible/activity/navigation/ExpListNavAdapter.java
index 52b571e..c8d400c 100644
--- a/app/src/main/java/org/bspeice/minimalbible/activity/viewer/BibleNavAdapter.java
+++ b/app/src/main/java/org/bspeice/minimalbible/activity/navigation/ExpListNavAdapter.java
@@ -1,4 +1,4 @@
-package org.bspeice.minimalbible.activity.viewer;
+package org.bspeice.minimalbible.activity.navigation;
import android.content.Context;
import android.view.LayoutInflater;
@@ -7,61 +7,44 @@ import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.TextView;
-import org.bspeice.minimalbible.Injector;
import org.bspeice.minimalbible.R;
-import org.bspeice.minimalbible.activity.viewer.bookutil.VersificationUtil;
-import org.crosswire.jsword.book.Book;
-import org.crosswire.jsword.versification.BibleBook;
-import org.crosswire.jsword.versification.Versification;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import javax.inject.Inject;
import butterknife.ButterKnife;
import butterknife.InjectView;
-import rx.functions.Action1;
/**
* ExpandableListView Navigation Drawer
- * TODO: Refactor out to ExpandableNavDrawerAdapter?
+ * T1 represents Group objects, T2 is child objects
+ * Not sure if I'll ever actually need to re-use this, but go ahead and make it generic.
+ * TODO: Document this.
*/
-public class BibleNavAdapter extends BaseExpandableListAdapter {
-
- @Inject
- VersificationUtil vUtil;
- Versification versification;
- Book book;
+public class ExpListNavAdapter extends BaseExpandableListAdapter {
// Now we could technically implement this structure using a LinkedHashMap, but
// it's easier both to understand and program if we implement this using two maps.
- Map indexableBibleBooks;
- Map chaptersForBook;
+ Map indexableBibleBooks;
+ Map> chaptersForBook;
private int groupHighlighted;
private int childHighlighted;
- public BibleNavAdapter(final Book b, Injector injector) {
- injector.inject(this);
- this.book = b;
- versification = vUtil.getVersification(book);
+ public ExpListNavAdapter(List groups, Map> children) {
// Let the map know ahead of time how big it will be
// int bookCount = versification.getBookCount();
- indexableBibleBooks = new HashMap();
- chaptersForBook = new HashMap();
+ indexableBibleBooks = new HashMap(groups.size());
+ chaptersForBook = new HashMap>(groups.size());
- final AtomicInteger counter = new AtomicInteger(0);
- vUtil.getBooks(book)
- .forEach(new Action1() {
- @Override
- public void call(BibleBook bibleBook) {
- indexableBibleBooks.put(counter.getAndIncrement(), bibleBook);
- chaptersForBook.put(bibleBook, vUtil.getChapterCount(b, bibleBook));
- }
- });
+ // Is it terrible that I don't like using an actual for loop?
+ for (int index = 0; index < groups.size(); index++) {
+ T1 gItem = groups.get(index);
+ indexableBibleBooks.put(index, gItem);
+ chaptersForBook.put(gItem, children.get(gItem));
+ }
}
@Override
@@ -71,25 +54,22 @@ public class BibleNavAdapter extends BaseExpandableListAdapter {
@Override
public int getChildrenCount(int i) {
- return chaptersForBook.get(indexableBibleBooks.get(i));
+ return chaptersForBook.get(indexableBibleBooks.get(i)).size();
}
@Override
- public String getGroup(int i) {
- return vUtil.getBookName(book, indexableBibleBooks.get(i));
+ public T1 getGroup(int i) {
+ return indexableBibleBooks.get(i);
}
/**
- * Take a shortcut - since the second item is the (indexed) chapter number,
- * we just need to add one to remove the off-by-one
- *
* @param i The group position
* @param i2 The child position
* @return The child chapter value
*/
@Override
- public Integer getChild(int i, int i2) {
- return i2 + 1;
+ public T2 getChild(int i, int i2) {
+ return chaptersForBook.get(indexableBibleBooks.get(i)).get(i2);
}
@Override
@@ -104,7 +84,7 @@ public class BibleNavAdapter extends BaseExpandableListAdapter {
@Override
public boolean hasStableIds() {
- return false;
+ return true;
}
/**
@@ -119,16 +99,16 @@ public class BibleNavAdapter extends BaseExpandableListAdapter {
@Override
public View getGroupView(int position, boolean expanded,
View convertView, ViewGroup parent) {
- NavItemHolder bookHolder;
+ NavItemHolder bookHolder;
if (convertView == null || convertView.getTag() == null) {
LayoutInflater inflater = (LayoutInflater) parent.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_navigation_drawer,
parent, false);
- bookHolder = new NavItemHolder(convertView);
+ bookHolder = new NavItemHolder(convertView);
convertView.setTag(bookHolder);
} else {
- bookHolder = (NavItemHolder) convertView.getTag();
+ bookHolder = (NavItemHolder) convertView.getTag();
}
bookHolder.bind(getGroup(position), position == groupHighlighted);
@@ -148,16 +128,16 @@ public class BibleNavAdapter extends BaseExpandableListAdapter {
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
- NavItemHolder chapterHolder;
+ NavItemHolder chapterHolder;
if (convertView == null || convertView.getTag() == null) {
LayoutInflater inflater = (LayoutInflater) parent.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_navigation_drawer,
parent, false);
- chapterHolder = new NavItemHolder(convertView);
+ chapterHolder = new NavItemHolder(convertView);
convertView.setTag(chapterHolder);
} else {
- chapterHolder = (NavItemHolder) convertView.getTag();
+ chapterHolder = (NavItemHolder) convertView.getTag();
}
chapterHolder.bind(getChild(groupPosition, childPosition),
@@ -180,8 +160,9 @@ public class BibleNavAdapter extends BaseExpandableListAdapter {
/**
* Class to hold elements for the navbar - doesn't matter if they're group or child.
+ * T3 is either T1 or T2, doesn't matter.
*/
- class NavItemHolder {
+ class NavItemHolder {
@InjectView(R.id.navlist_content)
TextView content;
@@ -192,7 +173,7 @@ public class BibleNavAdapter extends BaseExpandableListAdapter {
ButterKnife.inject(this, v);
}
- public void bind(T object, boolean highlighted) {
+ public void bind(T3 object, boolean highlighted) {
content.setText(object.toString());
if (highlighted) {
content.setTextColor(v.getResources().getColor(R.color.navbar_highlight));
diff --git a/app/src/main/java/org/bspeice/minimalbible/activity/NavDrawerAdapter.java b/app/src/main/java/org/bspeice/minimalbible/activity/navigation/ListNavAdapter.java
similarity index 93%
rename from app/src/main/java/org/bspeice/minimalbible/activity/NavDrawerAdapter.java
rename to app/src/main/java/org/bspeice/minimalbible/activity/navigation/ListNavAdapter.java
index 5572fca..2829d1f 100644
--- a/app/src/main/java/org/bspeice/minimalbible/activity/NavDrawerAdapter.java
+++ b/app/src/main/java/org/bspeice/minimalbible/activity/navigation/ListNavAdapter.java
@@ -1,4 +1,4 @@
-package org.bspeice.minimalbible.activity;
+package org.bspeice.minimalbible.activity.navigation;
import android.content.Context;
import android.view.LayoutInflater;
@@ -19,24 +19,24 @@ import butterknife.InjectView;
* This class (and its usage) needs some work refactoring,
* but the PoC is looking good!
*/
-public class NavDrawerAdapter extends BaseAdapter {
+public class ListNavAdapter extends BaseAdapter {
Context context;
List objects;
int currentlyHighlighted;
- public NavDrawerAdapter(Context context, List objects) {
+ public ListNavAdapter(Context context, List objects) {
this.context = context;
this.objects = objects;
}
- public void setCurrentlyHighlighted(int currentlyHighlighted) {
- this.currentlyHighlighted = currentlyHighlighted;
- }
-
public int getCurrentlyHighlighted() {
return this.currentlyHighlighted;
}
+ public void setCurrentlyHighlighted(int currentlyHighlighted) {
+ this.currentlyHighlighted = currentlyHighlighted;
+ }
+
@Override
public int getCount() {
return objects.size();
diff --git a/app/src/main/java/org/bspeice/minimalbible/activity/navigation/NavDrawerFragment.java b/app/src/main/java/org/bspeice/minimalbible/activity/navigation/NavDrawerFragment.java
new file mode 100644
index 0000000..fc78aee
--- /dev/null
+++ b/app/src/main/java/org/bspeice/minimalbible/activity/navigation/NavDrawerFragment.java
@@ -0,0 +1,299 @@
+package org.bspeice.minimalbible.activity.navigation;
+
+import android.app.Activity;
+import android.content.SharedPreferences;
+import android.content.res.Configuration;
+import android.os.Build;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.support.v4.app.ActionBarDrawerToggle;
+import android.support.v4.app.Fragment;
+import android.support.v4.view.GravityCompat;
+import android.support.v4.widget.DrawerLayout;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.ActionBarActivity;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.ExpandableListView;
+import android.widget.ListView;
+
+import com.readystatesoftware.systembartint.SystemBarTintManager;
+
+import org.bspeice.minimalbible.R;
+
+/**
+ * Fragment used for managing interactions for and presentation of a navigation
+ * drawer. See the design guidelines for a complete explanation of the behaviors
+ * implemented here.
+ * TODO: Refactor to allow ExpandableListView
+ */
+public class NavDrawerFragment extends Fragment {
+
+ /**
+ * Remember the position of the selected item.
+ */
+ private static final String STATE_SELECTED_POSITION = "selected_navigation_drawer_position";
+
+ /**
+ * Per the design guidelines, you should show the drawer on launch until the
+ * user manually expands it. This shared preference tracks this.
+ */
+ private static final String PREF_USER_LEARNED_DRAWER = "navigation_drawer_learned";
+ protected ListView mDrawerListView;
+ protected int mCurrentSelectedPosition = 0;
+ /**
+ * A pointer to the current callbacks instance (the Activity).
+ */
+ private NavigationDrawerCallbacks mCallbacks;
+ /**
+ * Helper component that ties the action bar to the navigation drawer.
+ */
+ private ActionBarDrawerToggle mDrawerToggle;
+ private DrawerLayout mDrawerLayout;
+ private View mFragmentContainerView;
+ private boolean mFromSavedInstanceState;
+ private boolean mUserLearnedDrawer;
+
+ public NavDrawerFragment() {
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Read in the flag indicating whether or not the user has demonstrated
+ // awareness of the
+ // drawer. See PREF_USER_LEARNED_DRAWER for details.
+ SharedPreferences sp = PreferenceManager
+ .getDefaultSharedPreferences(getActivity());
+ mUserLearnedDrawer = sp.getBoolean(PREF_USER_LEARNED_DRAWER, false);
+
+ if (savedInstanceState != null) {
+ mCurrentSelectedPosition = savedInstanceState
+ .getInt(STATE_SELECTED_POSITION);
+ mFromSavedInstanceState = true;
+ }
+
+ // Select either the default item (0) or the last selected item.
+ selectItem(mCurrentSelectedPosition);
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ // Indicate that this fragment would like to influence the set of
+ // actions in the action bar.
+ setHasOptionsMenu(true);
+ }
+
+ public boolean isDrawerOpen() {
+ return mDrawerLayout != null
+ && mDrawerLayout.isDrawerOpen(mFragmentContainerView);
+ }
+
+ /**
+ * Users of this fragment must call this method to set up the navigation
+ * drawer interactions.
+ *
+ * @param fragmentId The android:id of this fragment in its activity's layout.
+ * @param drawerLayout The DrawerLayout containing this fragment's UI.
+ */
+ public void setUp(int fragmentId, DrawerLayout drawerLayout) {
+ mFragmentContainerView = getActivity().findViewById(fragmentId);
+ mDrawerLayout = drawerLayout;
+
+ // set a custom shadow that overlays the main content when the drawer
+ // opens
+ mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow,
+ GravityCompat.START);
+ // set up the drawer's list view with items and click listener
+
+ ActionBar actionBar = getActionBar();
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setHomeButtonEnabled(true);
+
+ // ActionBarDrawerToggle ties together the the proper interactions
+ // between the navigation drawer and the action bar app icon.
+ mDrawerToggle = new ActionBarDrawerToggle(getActivity(), /* host Activity */
+ mDrawerLayout, /* DrawerLayout object */
+ R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */
+ R.string.navigation_drawer_open, /*
+ * "open drawer" description for
+ * accessibility
+ */
+ R.string.navigation_drawer_close /*
+ * "close drawer" description for
+ * accessibility
+ */
+ ) {
+ @Override
+ public void onDrawerClosed(View drawerView) {
+ super.onDrawerClosed(drawerView);
+ if (!isAdded()) {
+ return;
+ }
+
+ getActivity().supportInvalidateOptionsMenu(); // calls
+ // onPrepareOptionsMenu()
+ }
+
+ @Override
+ public void onDrawerOpened(View drawerView) {
+ super.onDrawerOpened(drawerView);
+ if (!isAdded()) {
+ return;
+ }
+
+ if (!mUserLearnedDrawer) {
+ // The user manually opened the drawer; store this flag to
+ // prevent auto-showing
+ // the navigation drawer automatically in the future.
+ mUserLearnedDrawer = true;
+ SharedPreferences sp = PreferenceManager
+ .getDefaultSharedPreferences(getActivity());
+ sp.edit().putBoolean(PREF_USER_LEARNED_DRAWER, true)
+ .commit();
+ }
+
+ getActivity().supportInvalidateOptionsMenu(); // calls
+ // onPrepareOptionsMenu()
+ }
+ };
+
+ // If the user hasn't 'learned' about the drawer, open it to introduce
+ // them to the drawer,
+ // per the navigation drawer design guidelines.
+ if (!mUserLearnedDrawer && !mFromSavedInstanceState) {
+ mDrawerLayout.openDrawer(mFragmentContainerView);
+ }
+
+ // Defer code dependent on restoration of previous instance state.
+ mDrawerLayout.post(new Runnable() {
+ @Override
+ public void run() {
+ mDrawerToggle.syncState();
+ }
+ });
+
+ mDrawerLayout.setDrawerListener(mDrawerToggle);
+ }
+
+ public void selectItem(int position) {
+ mCurrentSelectedPosition = position;
+ if (mDrawerListView != null) {
+ mDrawerListView.setItemChecked(position, true);
+ ((ListNavAdapter) mDrawerListView.getAdapter()).setCurrentlyHighlighted(position);
+ }
+ if (mDrawerLayout != null) {
+ mDrawerLayout.closeDrawer(mFragmentContainerView);
+ }
+ if (mCallbacks != null) {
+ mCallbacks.onNavigationDrawerItemSelected(position);
+ }
+ }
+
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+ try {
+ mCallbacks = (NavigationDrawerCallbacks) activity;
+ } catch (ClassCastException e) {
+ throw new ClassCastException(
+ "Activity must implement NavigationDrawerCallbacks.");
+ }
+ }
+
+ @Override
+ public void onDetach() {
+ super.onDetach();
+ mCallbacks = null;
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putInt(STATE_SELECTED_POSITION, mCurrentSelectedPosition);
+ }
+
+ @Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ // Forward the new configuration the drawer toggle component.
+ mDrawerToggle.onConfigurationChanged(newConfig);
+ }
+
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ // If the drawer is open, show the global app actions in the action bar.
+ // See also
+ // showGlobalContextActionBar, which controls the top-left area of the
+ // action bar.
+ if (mDrawerLayout != null && isDrawerOpen()) {
+ inflater.inflate(R.menu.global, menu);
+ showGlobalContextActionBar();
+ }
+ super.onCreateOptionsMenu(menu, inflater);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (mDrawerToggle.onOptionsItemSelected(item)) {
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ /**
+ * Per the navigation drawer design guidelines, updates the action bar to
+ * show the global app 'context', rather than just what's in the current
+ * screen.
+ */
+ private void showGlobalContextActionBar() {
+ ActionBar actionBar = getActionBar();
+ actionBar.setDisplayShowTitleEnabled(true);
+ actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
+ // actionBar.setTitle(R.string.app_name);
+ }
+
+ protected ActionBar getActionBar() {
+ return ((ActionBarActivity) getActivity()).getSupportActionBar();
+ }
+
+ public void setInsets(View view) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT)
+ return;
+ SystemBarTintManager tintManager = new SystemBarTintManager(getActivity());
+ SystemBarTintManager.SystemBarConfig config = tintManager.getConfig();
+ view.setPadding(0, config.getPixelInsetTop(true),
+ config.getPixelInsetRight(), config.getPixelInsetBottom());
+ }
+
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+
+ // This could also be a ScrollView
+ ExpandableListView list = (ExpandableListView) view.findViewById(R.id.list_nav_drawer);
+ // This could also be set in your layout, allows the list items to
+ // scroll through the bottom padded area (navigation bar)
+ list.setClipToPadding(false);
+ // Sets the padding to the insets (include action bar and navigation bar
+ // padding for the current device and orientation)
+ setInsets(list);
+ }
+
+ /**
+ * Callbacks interface that all activities using this fragment must
+ * implement.
+ */
+ public static interface NavigationDrawerCallbacks {
+ /**
+ * Called when an item in the navigation drawer is selected.
+ */
+ void onNavigationDrawerItemSelected(int position);
+ }
+}
diff --git a/app/src/main/java/org/bspeice/minimalbible/activity/viewer/BibleViewer.java b/app/src/main/java/org/bspeice/minimalbible/activity/viewer/BibleViewer.java
index d213a56..f854b6f 100644
--- a/app/src/main/java/org/bspeice/minimalbible/activity/viewer/BibleViewer.java
+++ b/app/src/main/java/org/bspeice/minimalbible/activity/viewer/BibleViewer.java
@@ -16,8 +16,8 @@ import org.bspeice.minimalbible.MinimalBible;
import org.bspeice.minimalbible.OGHolder;
import org.bspeice.minimalbible.R;
import org.bspeice.minimalbible.activity.BaseActivity;
-import org.bspeice.minimalbible.activity.BaseNavigationDrawerFragment;
import org.bspeice.minimalbible.activity.downloader.DownloadActivity;
+import org.bspeice.minimalbible.activity.navigation.NavDrawerFragment;
import org.crosswire.jsword.book.Book;
import javax.inject.Inject;
@@ -27,7 +27,7 @@ import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
public class BibleViewer extends BaseActivity implements
- BaseNavigationDrawerFragment.NavigationDrawerCallbacks,
+ NavDrawerFragment.NavigationDrawerCallbacks,
Injector {
@Inject BookManager bookManager;
@@ -37,7 +37,7 @@ public class BibleViewer extends BaseActivity implements
* Fragment managing the behaviors, interactions and presentation of the
* navigation drawer.
*/
- private ViewerNavDrawerFragment mNavigationDrawerFragment;
+ private ExpListNavDrawerFragment mNavigationDrawerFragment;
/**
* Used to store the last screen title. For use in
* {@link #restoreActionBar()}.
@@ -50,13 +50,11 @@ public class BibleViewer extends BaseActivity implements
private void buildObjGraph() {
if (bvObjectGraph == null) {
OGHolder holder = OGHolder.get(this);
- ObjectGraph holderGraph = holder.fetchGraph();
- if (holderGraph == null) {
+ bvObjectGraph = holder.fetchGraph();
+ if (bvObjectGraph == null) {
bvObjectGraph = MinimalBible.get(this)
.plus(new BibleViewerModules(this));
- holder.persistGraph(holderGraph);
- } else {
- bvObjectGraph = holderGraph;
+ holder.persistGraph(bvObjectGraph);
}
}
bvObjectGraph.inject(this);
@@ -98,9 +96,9 @@ public class BibleViewer extends BaseActivity implements
setContentView(R.layout.activity_bible_viewer);
- mNavigationDrawerFragment = (ViewerNavDrawerFragment) getSupportFragmentManager()
- .findFragmentById(R.id.navigation_drawer);
- mTitle = getTitle();
+ mNavigationDrawerFragment = (ExpListNavDrawerFragment) getSupportFragmentManager()
+ .findFragmentById(R.id.navigation_drawer);
+ mTitle = getTitle();
// Set up the drawer.
mNavigationDrawerFragment.setUp(R.id.navigation_drawer,
diff --git a/app/src/main/java/org/bspeice/minimalbible/activity/viewer/BibleViewerModules.java b/app/src/main/java/org/bspeice/minimalbible/activity/viewer/BibleViewerModules.java
index 0f60ea3..84b4e58 100644
--- a/app/src/main/java/org/bspeice/minimalbible/activity/viewer/BibleViewerModules.java
+++ b/app/src/main/java/org/bspeice/minimalbible/activity/viewer/BibleViewerModules.java
@@ -3,6 +3,7 @@ package org.bspeice.minimalbible.activity.viewer;
import android.util.Log;
import org.bspeice.minimalbible.Injector;
+import org.bspeice.minimalbible.activity.navigation.ExpListNavAdapter;
import org.bspeice.minimalbible.activity.viewer.bookutil.VersificationUtil;
import org.crosswire.jsword.book.Book;
@@ -24,8 +25,8 @@ import rx.functions.Func1;
injects = {
BibleViewer.class,
BookFragment.class,
- ViewerNavDrawerFragment.class,
- BibleNavAdapter.class
+ ExpListNavDrawerFragment.class,
+ ExpListNavAdapter.class
},
library = true
)
diff --git a/app/src/main/java/org/bspeice/minimalbible/activity/viewer/ExpListNavDrawerFragment.java b/app/src/main/java/org/bspeice/minimalbible/activity/viewer/ExpListNavDrawerFragment.java
new file mode 100644
index 0000000..474eab9
--- /dev/null
+++ b/app/src/main/java/org/bspeice/minimalbible/activity/viewer/ExpListNavDrawerFragment.java
@@ -0,0 +1,110 @@
+package org.bspeice.minimalbible.activity.viewer;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ExpandableListView;
+
+import org.bspeice.minimalbible.Injector;
+import org.bspeice.minimalbible.R;
+import org.bspeice.minimalbible.activity.navigation.ExpListNavAdapter;
+import org.bspeice.minimalbible.activity.navigation.NavDrawerFragment;
+import org.bspeice.minimalbible.activity.viewer.bookutil.VersificationUtil;
+import org.crosswire.jsword.book.Book;
+import org.crosswire.jsword.versification.BibleBook;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import rx.functions.Func1;
+import rx.functions.Func2;
+
+/**
+ * ExpandableListView for managing books of the Bible.
+ * We extend from @link{BaseNavigationDrawerFragment} so we can inherit some of the lifecycle
+ * pieces, but the actual view inflation is done by us.
+ * TODO: Extend BaseExpNavigationDrawerFragment?
+ */
+public class ExpListNavDrawerFragment extends NavDrawerFragment {
+
+ @Inject VersificationUtil vUtil;
+ @Inject @Named("MainBook")
+ Book mainBook;
+
+ ExpandableListView mActualListView;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ Injector i = (Injector) getActivity();
+ i.inject(this);
+
+ mActualListView = (ExpandableListView) inflater.inflate(
+ R.layout.fragment_expandable_navigation_drawer, container, false);
+ /*
+ mDrawerListView
+ .setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view,
+ int position, long id) {
+ selectItem(position);
+ }
+ });
+ */
+
+ List bibleBooks = vUtil.getBookNames(mainBook)
+ .toList().toBlocking().first();
+
+
+ // I really don't like how we build the chapters, but I'm not adding Guava just for Range.
+ // RXJava does get ridiculous with the angle brackets, you have me there. But Intellij
+ // folds nicely.
+ Map> chapterMap =
+ vUtil.getBooks(mainBook).map(new Func1>>() {
+ @Override
+ public Map> call(BibleBook bibleBook) {
+ // These lines are important
+ int bookCount = vUtil.getChapterCount(mainBook, bibleBook);
+ List chapterList = new ArrayList(bookCount);
+ for (int i = 0; i < bookCount; i++) {
+ chapterList.add(i + 1); // Index to chapter number
+ }
+ //
+ Map> bookListMap =
+ new HashMap>(1);
+ bookListMap.put(vUtil.getBookName(mainBook, bibleBook), chapterList);
+ return bookListMap;
+ }
+ })
+ .reduce(new Func2