mirror of
https://github.com/MinimalBible/MinimalBible
synced 2024-11-22 07:58:20 -05:00
[broken] Add initial ExpandableListView navbar
This commit is contained in:
parent
a0e9939954
commit
07f6705539
@ -16,6 +16,7 @@ import android.view.Menu;
|
|||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.widget.ExpandableListView;
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
|
|
||||||
import com.readystatesoftware.systembartint.SystemBarTintManager;
|
import com.readystatesoftware.systembartint.SystemBarTintManager;
|
||||||
@ -28,6 +29,7 @@ import org.bspeice.minimalbible.R;
|
|||||||
* "https://developer.android.com/design/patterns/navigation-drawer.html#Interaction"
|
* "https://developer.android.com/design/patterns/navigation-drawer.html#Interaction"
|
||||||
* > design guidelines</a> for a complete explanation of the behaviors
|
* > design guidelines</a> for a complete explanation of the behaviors
|
||||||
* implemented here.
|
* implemented here.
|
||||||
|
* TODO: Refactor to allow ExpandableListView
|
||||||
*/
|
*/
|
||||||
public class BaseNavigationDrawerFragment extends Fragment {
|
public class BaseNavigationDrawerFragment extends Fragment {
|
||||||
|
|
||||||
@ -41,22 +43,18 @@ public class BaseNavigationDrawerFragment extends Fragment {
|
|||||||
* user manually expands it. This shared preference tracks this.
|
* user manually expands it. This shared preference tracks this.
|
||||||
*/
|
*/
|
||||||
private static final String PREF_USER_LEARNED_DRAWER = "navigation_drawer_learned";
|
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).
|
/**
|
||||||
*/
|
* A pointer to the current callbacks instance (the Activity).
|
||||||
private NavigationDrawerCallbacks mCallbacks;
|
*/
|
||||||
|
private NavigationDrawerCallbacks mCallbacks;
|
||||||
/**
|
/**
|
||||||
* Helper component that ties the action bar to the navigation drawer.
|
* Helper component that ties the action bar to the navigation drawer.
|
||||||
*/
|
*/
|
||||||
private ActionBarDrawerToggle mDrawerToggle;
|
private ActionBarDrawerToggle mDrawerToggle;
|
||||||
|
|
||||||
private DrawerLayout mDrawerLayout;
|
private DrawerLayout mDrawerLayout;
|
||||||
protected ListView mDrawerListView;
|
|
||||||
private View mFragmentContainerView;
|
private View mFragmentContainerView;
|
||||||
|
|
||||||
protected int mCurrentSelectedPosition = 0;
|
|
||||||
private boolean mFromSavedInstanceState;
|
private boolean mFromSavedInstanceState;
|
||||||
private boolean mUserLearnedDrawer;
|
private boolean mUserLearnedDrawer;
|
||||||
|
|
||||||
@ -281,8 +279,8 @@ public class BaseNavigationDrawerFragment extends Fragment {
|
|||||||
super.onViewCreated(view, savedInstanceState);
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
|
||||||
// This could also be a ScrollView
|
// This could also be a ScrollView
|
||||||
ListView list = (ListView) view.findViewById(R.id.list_nav_drawer);
|
ExpandableListView list = (ExpandableListView) view.findViewById(R.id.list_nav_drawer);
|
||||||
// This could also be set in your layout, allows the list items to
|
// This could also be set in your layout, allows the list items to
|
||||||
// scroll through the bottom padded area (navigation bar)
|
// scroll through the bottom padded area (navigation bar)
|
||||||
list.setClipToPadding(false);
|
list.setClipToPadding(false);
|
||||||
// Sets the padding to the insets (include action bar and navigation bar
|
// Sets the padding to the insets (include action bar and navigation bar
|
||||||
|
@ -0,0 +1,200 @@
|
|||||||
|
package org.bspeice.minimalbible.activity.viewer;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
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.Map;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import butterknife.ButterKnife;
|
||||||
|
import butterknife.InjectView;
|
||||||
|
import rx.functions.Action1;
|
||||||
|
|
||||||
|
public class BibleNavAdapter extends BaseExpandableListAdapter {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
VersificationUtil vUtil;
|
||||||
|
Versification versification;
|
||||||
|
Book book;
|
||||||
|
|
||||||
|
// 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<Integer, BibleBook> indexableBibleBooks;
|
||||||
|
Map<BibleBook, Integer> chaptersForBook;
|
||||||
|
|
||||||
|
private int groupHighlighted;
|
||||||
|
private int childHighlighted;
|
||||||
|
|
||||||
|
public BibleNavAdapter(final Book b, Injector injector) {
|
||||||
|
injector.inject(this);
|
||||||
|
this.book = b;
|
||||||
|
versification = vUtil.getVersification(book);
|
||||||
|
|
||||||
|
// Let the map know ahead of time how big it will be
|
||||||
|
// int bookCount = versification.getBookCount();
|
||||||
|
indexableBibleBooks = new HashMap<Integer, BibleBook>();
|
||||||
|
chaptersForBook = new HashMap<BibleBook, Integer>();
|
||||||
|
|
||||||
|
final AtomicInteger counter = new AtomicInteger(0);
|
||||||
|
vUtil.getBooks(book)
|
||||||
|
.forEach(new Action1<BibleBook>() {
|
||||||
|
@Override
|
||||||
|
public void call(BibleBook bibleBook) {
|
||||||
|
indexableBibleBooks.put(counter.getAndIncrement(), bibleBook);
|
||||||
|
chaptersForBook.put(bibleBook, vUtil.getChapterCount(b, bibleBook));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getGroupCount() {
|
||||||
|
return indexableBibleBooks.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getChildrenCount(int i) {
|
||||||
|
return chaptersForBook.get(indexableBibleBooks.get(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getGroup(int i) {
|
||||||
|
return vUtil.getBookName(book, 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getGroupId(int i) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getChildId(int i, int i2) {
|
||||||
|
return i2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasStableIds() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the views for this group
|
||||||
|
*
|
||||||
|
* @param position
|
||||||
|
* @param expanded
|
||||||
|
* @param convertView
|
||||||
|
* @param parent
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public View getGroupView(int position, boolean expanded,
|
||||||
|
View convertView, ViewGroup parent) {
|
||||||
|
NavItemHolder<String> 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<String>(convertView);
|
||||||
|
convertView.setTag(bookHolder);
|
||||||
|
} else {
|
||||||
|
bookHolder = (NavItemHolder<String>) convertView.getTag();
|
||||||
|
}
|
||||||
|
|
||||||
|
bookHolder.bind(getGroup(position), position == groupHighlighted);
|
||||||
|
return convertView;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the view for a child
|
||||||
|
*
|
||||||
|
* @param groupPosition
|
||||||
|
* @param childPosition
|
||||||
|
* @param isLastChild
|
||||||
|
* @param convertView
|
||||||
|
* @param parent
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public View getChildView(int groupPosition, int childPosition,
|
||||||
|
boolean isLastChild, View convertView, ViewGroup parent) {
|
||||||
|
NavItemHolder<Integer> 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<Integer>(convertView);
|
||||||
|
convertView.setTag(chapterHolder);
|
||||||
|
} else {
|
||||||
|
chapterHolder = (NavItemHolder<Integer>) convertView.getTag();
|
||||||
|
}
|
||||||
|
|
||||||
|
chapterHolder.bind(getChild(groupPosition, childPosition),
|
||||||
|
childPosition == childHighlighted);
|
||||||
|
return convertView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isChildSelectable(int i, int i2) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGroupHighlighted(int groupHighlighted) {
|
||||||
|
this.groupHighlighted = groupHighlighted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChildHighlighted(int childHighlighted) {
|
||||||
|
this.childHighlighted = childHighlighted;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to hold elements for the navbar - doesn't matter if they're group or child.
|
||||||
|
*/
|
||||||
|
class NavItemHolder<T> {
|
||||||
|
@InjectView(R.id.navlist_content)
|
||||||
|
TextView content;
|
||||||
|
|
||||||
|
View v;
|
||||||
|
|
||||||
|
public NavItemHolder(View v) {
|
||||||
|
this.v = v; // Needed for resolving colors below
|
||||||
|
ButterKnife.inject(this, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bind(T object, boolean highlighted) {
|
||||||
|
content.setText(object.toString());
|
||||||
|
if (highlighted) {
|
||||||
|
content.setTextColor(v.getResources().getColor(R.color.navbar_highlight));
|
||||||
|
} else {
|
||||||
|
content.setTextColor(v.getResources().getColor(R.color.navbar_unhighlighted));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -24,7 +24,8 @@ import rx.functions.Func1;
|
|||||||
injects = {
|
injects = {
|
||||||
BibleViewer.class,
|
BibleViewer.class,
|
||||||
BookFragment.class,
|
BookFragment.class,
|
||||||
ViewerNavDrawerFragment.class
|
ViewerNavDrawerFragment.class,
|
||||||
|
BibleNavAdapter.class
|
||||||
},
|
},
|
||||||
library = true
|
library = true
|
||||||
)
|
)
|
||||||
@ -35,17 +36,20 @@ public class BibleViewerModules {
|
|||||||
this.activity = activity;
|
this.activity = activity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides @Singleton
|
@Provides
|
||||||
|
@Singleton
|
||||||
Injector provideInjector() {
|
Injector provideInjector() {
|
||||||
return activity;
|
return activity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides @Singleton
|
@Provides
|
||||||
|
@Singleton
|
||||||
BibleViewerPreferences providePrefs() {
|
BibleViewerPreferences providePrefs() {
|
||||||
return Esperandro.getPreferences(BibleViewerPreferences.class, activity);
|
return Esperandro.getPreferences(BibleViewerPreferences.class, activity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides @Named("MainBook")
|
@Provides
|
||||||
|
@Named("MainBook")
|
||||||
Book provideMainBook(BookManager bookManager, final BibleViewerPreferences prefs) {
|
Book provideMainBook(BookManager bookManager, final BibleViewerPreferences prefs) {
|
||||||
final AtomicReference<Book> mBook = new AtomicReference<Book>(null);
|
final AtomicReference<Book> mBook = new AtomicReference<Book>(null);
|
||||||
bookManager.getInstalledBooks()
|
bookManager.getInstalledBooks()
|
||||||
@ -60,7 +64,7 @@ public class BibleViewerModules {
|
|||||||
public void call(Book book) {
|
public void call(Book book) {
|
||||||
mBook.set(book);
|
mBook.set(book);
|
||||||
}
|
}
|
||||||
},new Action1<Throwable>() {
|
}, new Action1<Throwable>() {
|
||||||
@Override
|
@Override
|
||||||
public void call(Throwable throwable) {
|
public void call(Throwable throwable) {
|
||||||
Log.d("BibleViewerModules", throwable.getLocalizedMessage());
|
Log.d("BibleViewerModules", throwable.getLocalizedMessage());
|
||||||
|
@ -4,49 +4,52 @@ import android.os.Bundle;
|
|||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.AdapterView;
|
import android.widget.ExpandableListView;
|
||||||
import android.widget.ListView;
|
|
||||||
|
|
||||||
import org.bspeice.minimalbible.Injector;
|
import org.bspeice.minimalbible.Injector;
|
||||||
import org.bspeice.minimalbible.R;
|
import org.bspeice.minimalbible.R;
|
||||||
import org.bspeice.minimalbible.activity.BaseNavigationDrawerFragment;
|
import org.bspeice.minimalbible.activity.BaseNavigationDrawerFragment;
|
||||||
import org.bspeice.minimalbible.activity.NavDrawerAdapter;
|
|
||||||
import org.bspeice.minimalbible.activity.viewer.bookutil.VersificationUtil;
|
import org.bspeice.minimalbible.activity.viewer.bookutil.VersificationUtil;
|
||||||
import org.crosswire.jsword.book.Book;
|
import org.crosswire.jsword.book.Book;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
public class ViewerNavDrawerFragment extends BaseNavigationDrawerFragment {
|
public class ViewerNavDrawerFragment extends BaseNavigationDrawerFragment {
|
||||||
|
|
||||||
@Inject VersificationUtil vUtil;
|
@Inject VersificationUtil vUtil;
|
||||||
@Inject @Named("MainBook")
|
@Inject @Named("MainBook")
|
||||||
Book mainBook;
|
Book mainBook;
|
||||||
|
|
||||||
|
ExpandableListView mActualListView;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
((Injector)getActivity()).inject(this);
|
Injector i = (Injector) getActivity();
|
||||||
|
i.inject(this);
|
||||||
|
|
||||||
mDrawerListView = (ListView) inflater.inflate(
|
mActualListView = (ExpandableListView) inflater.inflate(
|
||||||
R.layout.fragment_navigation_drawer, container, false);
|
R.layout.fragment_expandable_navigation_drawer, container, false);
|
||||||
mDrawerListView
|
/*
|
||||||
|
mDrawerListView
|
||||||
.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onItemClick(AdapterView<?> parent, View view,
|
public void onItemClick(AdapterView<?> parent, View view,
|
||||||
int position, long id) {
|
int position, long id) {
|
||||||
selectItem(position);
|
selectItem(position);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
List<String> bookNames = vUtil.getNiceBookNames(mainBook)
|
*/
|
||||||
.toList().toBlocking().first();
|
|
||||||
|
|
||||||
mDrawerListView.setAdapter(new NavDrawerAdapter<String>(getActionBar()
|
mActualListView.setAdapter(new BibleNavAdapter(mainBook, i));
|
||||||
.getThemedContext(), bookNames));
|
|
||||||
|
|
||||||
mDrawerListView.setItemChecked(mCurrentSelectedPosition, true);
|
mActualListView.setItemChecked(mCurrentSelectedPosition, true);
|
||||||
return mDrawerListView;
|
return mActualListView;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,13 +24,14 @@ public class VersificationUtil {
|
|||||||
add(BibleBook.INTRO_NT);
|
add(BibleBook.INTRO_NT);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
// TODO: Cache the versification?
|
||||||
public Versification getVersification(Book b) {
|
public Versification getVersification(Book b) {
|
||||||
return Versifications.instance().getVersification(
|
return Versifications.instance().getVersification(
|
||||||
(String) b.getBookMetaData().getProperty(BookMetaData.KEY_VERSIFICATION)
|
(String) b.getBookMetaData().getProperty(BookMetaData.KEY_VERSIFICATION)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Observable<BibleBook> getBookNames(Book b) {
|
public Observable<BibleBook> getBooks(Book b) {
|
||||||
Versification v = getVersification(b);
|
Versification v = getVersification(b);
|
||||||
return Observable.from(IteratorUtil.copyIterator(v.getBookIterator()))
|
return Observable.from(IteratorUtil.copyIterator(v.getBookIterator()))
|
||||||
.filter(new Func1<BibleBook, Boolean>() {
|
.filter(new Func1<BibleBook, Boolean>() {
|
||||||
@ -41,14 +42,21 @@ public class VersificationUtil {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public Observable<String> getNiceBookNames(final Book b) {
|
public Observable<String> getBookNames(final Book b) {
|
||||||
|
return getBooks(b)
|
||||||
return getBookNames(b)
|
|
||||||
.map(new Func1<BibleBook, String>() {
|
.map(new Func1<BibleBook, String>() {
|
||||||
@Override
|
@Override
|
||||||
public String call(BibleBook bibleBook) {
|
public String call(BibleBook bibleBook) {
|
||||||
return getVersification(b).getLongName(bibleBook);
|
return getBookName(b, bibleBook);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Integer getChapterCount(Book b, BibleBook bibleBook) {
|
||||||
|
return getVersification(b).getLastChapter(bibleBook);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBookName(Book book, BibleBook bibleBook) {
|
||||||
|
return getVersification(book).getLongName(bibleBook);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
<ExpandableListView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/list_nav_drawer"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="#cccccc"
|
||||||
|
android:choiceMode="singleChoice"
|
||||||
|
android:divider="@android:color/transparent"
|
||||||
|
android:dividerHeight="0dp"
|
||||||
|
tools:context="org.bspeice.minimalbible.activity.viewer.ViewerNavDrawerFragment">
|
||||||
|
|
||||||
|
</ExpandableListView>
|
Loading…
Reference in New Issue
Block a user