mirror of
https://github.com/MinimalBible/MinimalBible
synced 2024-11-05 07:38:20 -05:00
Everything now responds to scroll events correctly!
Time for another release shortly, need to add some testing code and likely do some quick refactor work. Pretty happy where everything's at though, honestly.
This commit is contained in:
parent
c70c258231
commit
07015fc2ba
@ -23,6 +23,8 @@ import javax.inject.Named;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.InjectView;
|
||||
import dagger.ObjectGraph;
|
||||
import rx.functions.Action1;
|
||||
import rx.subjects.PublishSubject;
|
||||
|
||||
public class BibleViewer extends BaseActivity implements Injector {
|
||||
|
||||
@ -33,6 +35,9 @@ public class BibleViewer extends BaseActivity implements Injector {
|
||||
@Inject
|
||||
BibleViewerPreferences prefs;
|
||||
|
||||
@Inject
|
||||
PublishSubject<BookScrollEvent> scrollEventPublisher;
|
||||
|
||||
@InjectView(R.id.navigation_drawer)
|
||||
BibleMenu bibleMenu;
|
||||
|
||||
@ -101,10 +106,29 @@ public class BibleViewer extends BaseActivity implements Injector {
|
||||
|
||||
setInsetToolbar(toolbar);
|
||||
|
||||
// Currently you must set up the menu in exactly this order. Do I need to refactor this?
|
||||
bibleMenu.setScrollEventPublisher(scrollEventPublisher);
|
||||
bibleMenu.setBible(mainBook);
|
||||
|
||||
// If a new chapter is selected, make sure we close the drawer
|
||||
// We can't specify `this` as the subscriber since we can't
|
||||
// extend Action1
|
||||
scrollEventPublisher.subscribe(new Action1<BookScrollEvent>() {
|
||||
@Override
|
||||
public void call(BookScrollEvent bookScrollEvent) {
|
||||
closeMenu();
|
||||
}
|
||||
});
|
||||
|
||||
// Set up the view to respond to scroll events as well. Again, exact order is needed.
|
||||
bibleContent.setScrollPublisher(scrollEventPublisher);
|
||||
bibleContent.setBook(mainBook, prefs);
|
||||
}
|
||||
|
||||
public void closeMenu() {
|
||||
drawerLayout.closeDrawers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.viewer, menu);
|
||||
|
@ -16,6 +16,7 @@ import dagger.Provides;
|
||||
import de.devland.esperandro.Esperandro;
|
||||
import rx.functions.Action1;
|
||||
import rx.functions.Func1;
|
||||
import rx.subjects.PublishSubject;
|
||||
|
||||
/**
|
||||
* Modules used for the BibleViewer activity
|
||||
@ -92,4 +93,10 @@ public class BibleViewerModules {
|
||||
BookManager bookManager() {
|
||||
return new BookManager();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
PublishSubject<BookScrollEvent> scrollEventPublisher() {
|
||||
return PublishSubject.create();
|
||||
}
|
||||
}
|
@ -20,9 +20,11 @@ import android.util.AttributeSet
|
||||
import kotlin.properties.Delegates
|
||||
import org.bspeice.minimalbible.activity.setInset
|
||||
import android.support.annotation.LayoutRes
|
||||
import org.crosswire.jsword.versification.BibleBook
|
||||
|
||||
class BibleMenu(val ctx: Context, val attrs: AttributeSet) : LinearLayout(ctx, attrs) {
|
||||
var menuContent: ExpandableListView by Delegates.notNull();
|
||||
var menuContent: ExpandableListView by Delegates.notNull()
|
||||
var scrollEventPublisher: PublishSubject<BookScrollEvent> by Delegates.notNull();
|
||||
|
||||
{
|
||||
val inflater = ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
|
||||
@ -31,7 +33,13 @@ class BibleMenu(val ctx: Context, val attrs: AttributeSet) : LinearLayout(ctx, a
|
||||
menuContent = findViewById(R.id._bible_menu) as ExpandableListView
|
||||
}
|
||||
|
||||
fun setBible(b: Book) = menuContent.setAdapter(BibleAdapter(b))
|
||||
fun setBible(b: Book) {
|
||||
val adapter = BibleAdapter(b, scrollEventPublisher)
|
||||
menuContent setAdapter adapter
|
||||
scrollEventPublisher subscribe {
|
||||
menuContent.collapseGroup(adapter.getGroupIdForBook(it.b))
|
||||
}
|
||||
}
|
||||
|
||||
fun placeInset(a: Activity) = setInset(a)
|
||||
}
|
||||
@ -48,30 +56,17 @@ class BibleMenu(val ctx: Context, val attrs: AttributeSet) : LinearLayout(ctx, a
|
||||
* TODO: Refactor this so the math parts are separate from the actual override functions,
|
||||
* so it's easier to test.
|
||||
*/
|
||||
class BibleAdapter(val b: Book) : BaseExpandableListAdapter() {
|
||||
class BibleAdapter(val b: Book, val scrollPublisher: PublishSubject<BookScrollEvent>)
|
||||
: BaseExpandableListAdapter() {
|
||||
|
||||
// Map BibleBooks to the number of chapters they have
|
||||
val menuMappings = b.getVersification().getBooks().map {
|
||||
Pair(it, b.getVersification().getLastChapter(it))
|
||||
}
|
||||
|
||||
/**
|
||||
* The listener that should be registered to receive click events
|
||||
* It's created here because we need access to the menuMappings
|
||||
*/
|
||||
fun getMenuClickListener(listener: PublishSubject<BookScrollEvent>) =
|
||||
object : ExpandableListView.OnChildClickListener {
|
||||
override fun onChildClick(listView: ExpandableListView?, childView: View?,
|
||||
groupPosition: Int, childPosition: Int, id: Long): Boolean {
|
||||
|
||||
val map = menuMappings[groupPosition]
|
||||
// childPosition is index-based
|
||||
// TODO: Figure out why trying chapter 0 triggers a NotImplementedException...
|
||||
listener onNext BookScrollEvent(map.first, childPosition + 1)
|
||||
|
||||
return true; // Event was handled
|
||||
}
|
||||
}
|
||||
fun getGroupIdForBook(b: BibleBook) = menuMappings.indexOf(
|
||||
menuMappings.first { it.first == b }
|
||||
)
|
||||
|
||||
var groupHighlighted: Int = 0
|
||||
var childHighlighted: Int = 0
|
||||
@ -129,7 +124,9 @@ class BibleAdapter(val b: Book) : BaseExpandableListAdapter() {
|
||||
chapterStart + 2
|
||||
val view = ChildItemHolder.init(
|
||||
getOrInflate(convertView, parent, R.layout.list_bible_menu_child),
|
||||
chapterStart..chapterEnd
|
||||
chapterStart..chapterEnd,
|
||||
menuMappings[group].first,
|
||||
scrollPublisher
|
||||
)
|
||||
|
||||
return view
|
||||
@ -170,16 +167,18 @@ class GroupItemHolder(val bindTo: View) {
|
||||
* Bind the child items. There are some funky math things going on since
|
||||
* we display three chapters per row, check the adapter for more documentation
|
||||
*/
|
||||
class ChildItemHolder(val bindTo: View) {
|
||||
class ChildItemHolder(val bindTo: View, val book: BibleBook,
|
||||
val scrollPublisher: PublishSubject<BookScrollEvent>) {
|
||||
val content1 = bindTo.findViewById(R.id.content1) as TextView
|
||||
val content2 = bindTo.findViewById(R.id.content2) as TextView
|
||||
val content3 = bindTo.findViewById(R.id.content3) as TextView
|
||||
|
||||
class object {
|
||||
fun init(v: View, obj: IntRange): View {
|
||||
fun init(v: View, obj: IntRange, book: BibleBook,
|
||||
scrollPublisher: PublishSubject<BookScrollEvent>): View {
|
||||
val holder =
|
||||
if (v.getTag() != null) v.getTag() as ChildItemHolder
|
||||
else ChildItemHolder(v)
|
||||
else ChildItemHolder(v, book, scrollPublisher)
|
||||
|
||||
holder.clearViews()
|
||||
holder.bind(obj)
|
||||
@ -187,6 +186,9 @@ class ChildItemHolder(val bindTo: View) {
|
||||
}
|
||||
}
|
||||
|
||||
fun buildOnClickListener(chapter: Int): View.OnClickListener =
|
||||
View.OnClickListener { scrollPublisher onNext BookScrollEvent(book, chapter) }
|
||||
|
||||
// Clear the views before binding, so that we don't have stale text left
|
||||
// as a result of recycling. There should probably be a different way of doing this,
|
||||
// but get something that works first.
|
||||
@ -211,6 +213,8 @@ class ChildItemHolder(val bindTo: View) {
|
||||
* Set up the view with the data we want to display
|
||||
*/
|
||||
fun bind(range: IntRange) = range.forEach {
|
||||
getViewForPosition(it) setText it.toString()
|
||||
val view = getViewForPosition(it)
|
||||
view setText it.toString()
|
||||
view setOnClickListener buildOnClickListener(it)
|
||||
}
|
||||
}
|
||||
|
@ -22,19 +22,23 @@ import android.support.v7.widget.LinearLayoutManager
|
||||
import android.widget.LinearLayout
|
||||
|
||||
class BibleView(val ctx: Context, val attrs: AttributeSet) : LinearLayout(ctx, attrs) {
|
||||
var bibleContent: RecyclerView by Delegates.notNull();
|
||||
var bibleContent: RecyclerView by Delegates.notNull()
|
||||
var scrollPublisher: PublishSubject<BookScrollEvent> by Delegates.notNull()
|
||||
|
||||
val layoutManager: LinearLayoutManager = LinearLayoutManager(ctx)
|
||||
val inflater = ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater;
|
||||
|
||||
{
|
||||
val inflater = ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
|
||||
// Don't attach yet, as we haven't finished setup
|
||||
val rootView = inflater.inflate(R.layout.view_bible, this, true)
|
||||
|
||||
bibleContent = rootView.findViewById(R.id.bible_content) as RecyclerView
|
||||
bibleContent setLayoutManager LinearLayoutManager(ctx)
|
||||
bibleContent setLayoutManager layoutManager
|
||||
}
|
||||
|
||||
fun setBook(b: Book, prefs: BibleViewerPreferences) {
|
||||
bibleContent setAdapter BookAdapter(b, prefs)
|
||||
val adapter = BookAdapter(b, prefs)
|
||||
adapter.bindScrollHandler(scrollPublisher, layoutManager)
|
||||
bibleContent setAdapter adapter
|
||||
}
|
||||
}
|
||||
|
||||
@ -114,7 +118,7 @@ class BookAdapter(val b: Book, val prefs: BibleViewerPreferences)
|
||||
*/
|
||||
override fun getItemCount(): Int = chapterCount
|
||||
|
||||
fun bindScrollHandler(provider: PublishSubject<BookScrollEvent>,
|
||||
public fun bindScrollHandler(provider: PublishSubject<BookScrollEvent>,
|
||||
lM: RecyclerView.LayoutManager) {
|
||||
provider subscribe {
|
||||
val event = it
|
||||
|
Loading…
Reference in New Issue
Block a user