Moving more code around for some more experimental android ui changes.

This commit is contained in:
casey langen 2019-02-13 19:11:54 -08:00
parent e159878713
commit 47953697ff
8 changed files with 112 additions and 21 deletions

View File

@ -15,7 +15,9 @@ import io.casey.musikcube.remote.ui.albums.constant.Album
import io.casey.musikcube.remote.ui.shared.activity.IFilterable
import io.casey.musikcube.remote.ui.shared.activity.ITitleProvider
import io.casey.musikcube.remote.ui.shared.activity.ITransportObserver
import io.casey.musikcube.remote.ui.shared.extension.getLayoutId
import io.casey.musikcube.remote.ui.shared.extension.initSearchMenu
import io.casey.musikcube.remote.ui.shared.extension.initToolbarIfNecessary
import io.casey.musikcube.remote.ui.shared.extension.setupDefaultRecyclerView
import io.casey.musikcube.remote.ui.shared.fragment.BaseFragment
import io.casey.musikcube.remote.ui.shared.mixin.DataProviderMixin
@ -55,7 +57,7 @@ class AlbumBrowseFragment: BaseFragment(), IFilterable, ITitleProvider, ITranspo
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
inflater.inflate(R.layout.recycler_view_fragment, container, false).apply {
inflater.inflate(this.getLayoutId(), container, false).apply {
val recyclerView = findViewById<FastScrollRecyclerView>(R.id.recycler_view)
setupDefaultRecyclerView(recyclerView, adapter)
@ -63,6 +65,8 @@ class AlbumBrowseFragment: BaseFragment(), IFilterable, ITitleProvider, ITranspo
emptyView.capability = EmptyListView.Capability.OnlineOnly
emptyView.emptyMessage = getString(R.string.empty_no_items_format, getString(R.string.browse_type_albums))
emptyView.alternateView = recyclerView
initToolbarIfNecessary(this)
}
override fun onResume() {

View File

@ -22,9 +22,7 @@ import io.casey.musikcube.remote.ui.shared.activity.IFabConsumer
import io.casey.musikcube.remote.ui.shared.activity.IFilterable
import io.casey.musikcube.remote.ui.shared.activity.ITitleProvider
import io.casey.musikcube.remote.ui.shared.activity.ITransportObserver
import io.casey.musikcube.remote.ui.shared.extension.EXTRA_ACTIVITY_TITLE
import io.casey.musikcube.remote.ui.shared.extension.initSearchMenu
import io.casey.musikcube.remote.ui.shared.extension.setupDefaultRecyclerView
import io.casey.musikcube.remote.ui.shared.extension.*
import io.casey.musikcube.remote.ui.shared.fragment.BaseFragment
import io.casey.musikcube.remote.ui.shared.mixin.DataProviderMixin
import io.casey.musikcube.remote.ui.shared.mixin.ItemContextMenuMixin
@ -73,7 +71,7 @@ class CategoryBrowseFragment: BaseFragment(), IFilterable, ITitleProvider, ITran
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? =
inflater.inflate(R.layout.recycler_view_fragment, container, false).apply {
inflater.inflate(this.getLayoutId(), container, false).apply {
this@CategoryBrowseFragment.rootView = this
val recyclerView = findViewById<FastScrollRecyclerView>(R.id.recycler_view)
@ -84,6 +82,7 @@ class CategoryBrowseFragment: BaseFragment(), IFilterable, ITitleProvider, ITran
emptyView.alternateView = recyclerView
setupDefaultRecyclerView(recyclerView, adapter)
initToolbarIfNecessary(this)
}
override fun onFabPress(fab: FloatingActionButton) {

View File

@ -3,6 +3,7 @@ package io.casey.musikcube.remote.ui.shared.activity
import android.os.Bundle
import android.support.design.widget.FloatingActionButton
import android.view.Menu
import android.view.MenuItem
import io.casey.musikcube.remote.R
import io.casey.musikcube.remote.ui.shared.extension.enableUpNavigation
import io.casey.musikcube.remote.ui.shared.extension.findFragment
@ -49,15 +50,32 @@ abstract class FragmentActivityWithTransport: BaseActivity(), IFilterable {
override fun onResume() {
super.onResume()
(content as? ITitleProvider)?.run {
setTitleFromIntent(this.title)
if (!content.hasToolbar) {
(content as? ITitleProvider)?.run {
setTitleFromIntent(this.title)
}
}
}
override fun onCreateOptionsMenu(menu: Menu): Boolean =
(content as? IMenuProvider)?.run {
return this.createOptionsMenu(menu)
} ?: false
override fun onCreateOptionsMenu(menu: Menu): Boolean {
if (!content.hasToolbar) {
(content as? IMenuProvider)?.run {
return this.createOptionsMenu(menu)
}
}
return false
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (!content.hasToolbar) {
(content as? IMenuProvider)?.run {
if (this.optionsItemSelected(item)) {
return true
}
}
}
return super.onOptionsItemSelected(item)
}
override fun setFilter(filter: String) =
(content as? IFilterable)?.run {

View File

@ -1,7 +1,9 @@
package io.casey.musikcube.remote.ui.shared.activity
import android.view.Menu
import android.view.MenuItem
interface IMenuProvider {
fun createOptionsMenu(menu: Menu): Boolean
fun optionsItemSelected(menuItem: MenuItem): Boolean
}

View File

@ -2,7 +2,9 @@ package io.casey.musikcube.remote.ui.shared.extension
import android.app.SearchManager
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.os.Bundle
import android.support.design.widget.Snackbar
import android.support.v4.app.DialogFragment
import android.support.v4.app.Fragment
@ -23,11 +25,14 @@ import io.casey.musikcube.remote.Application
import io.casey.musikcube.remote.R
import io.casey.musikcube.remote.ui.settings.constants.Prefs
import io.casey.musikcube.remote.ui.shared.activity.IFilterable
import io.casey.musikcube.remote.ui.shared.activity.IMenuProvider
import io.casey.musikcube.remote.ui.shared.fragment.BaseFragment
import io.casey.musikcube.remote.ui.shared.fragment.TransportFragment
import io.casey.musikcube.remote.util.Strings
const val EXTRA_ACTIVITY_TITLE = "extra_title"
const val EXTRA_WITH_TOOLBAR = "extra_with_toolbar"
const val EXTRA_WITH_FRAGMENT_TOOLBAR = "extra_with_fragment_toolbar"
fun AppCompatActivity.setupDefaultRecyclerView(
recyclerView: RecyclerView, adapter: RecyclerView.Adapter<*>)
@ -129,6 +134,15 @@ fun AppCompatActivity.initSearchMenu(menu: Menu, filterable: IFilterable?): Bool
fun Fragment.initSearchMenu(menu: Menu, filterable: IFilterable?): Boolean =
(activity as AppCompatActivity).initSearchMenu(menu, filterable)
fun Toolbar.initSearchMenu(filterable: IFilterable?): Boolean =
(context as AppCompatActivity).initSearchMenu(this.menu, filterable)
fun Toolbar.setTitleFromIntent(defaultTitle: String) {
val extras = (context as? AppCompatActivity)?.intent?.extras ?: Bundle()
val title = extras.getString(EXTRA_ACTIVITY_TITLE)
this.title = if (Strings.notEmpty(title)) title else defaultTitle
}
fun CheckBox.setCheckWithoutEvent(checked: Boolean,
listener: (CompoundButton, Boolean) -> Unit) {
this.setOnCheckedChangeListener(null)
@ -271,4 +285,41 @@ inline fun <reified T> FragmentManager.find(tag: String): T {
inline fun <reified T> AppCompatActivity.findFragment(tag: String): T {
return this.supportFragmentManager.find(tag)
}
inline fun <reified T: BaseFragment> T.withToolbar(): T {
if (this.arguments == null) {
this.arguments = Bundle()
}
this.arguments?.putBoolean(EXTRA_WITH_TOOLBAR, true)
return this
}
fun BaseFragment.initToolbarIfNecessary(view: View) {
view.findViewById<Toolbar>(R.id.toolbar)?.let {
it.navigationIcon = appCompatActivity.getDrawable(R.drawable.ic_back)
it.setNavigationOnClickListener { appCompatActivity.finish() }
it.initSearchMenu(this as? IFilterable)
if (this is IMenuProvider) {
this.createOptionsMenu(it.menu)
it.setOnMenuItemClickListener {
menuItem -> this.optionsItemSelected(menuItem)
}
}
}
}
fun BaseFragment.getLayoutId(): Int =
when (this.extras.getBoolean(EXTRA_WITH_TOOLBAR)) {
true -> R.layout.recycler_view_activity
else -> R.layout.recycler_view_fragment
}
fun Intent.withFragmentToolbar(): Intent {
this.putExtra(EXTRA_WITH_FRAGMENT_TOOLBAR, true)
return this
}
fun Intent?.hasFragmentToolbar(): Boolean {
return this?.getBooleanExtra(EXTRA_WITH_FRAGMENT_TOOLBAR, false) ?: false
}

View File

@ -7,13 +7,17 @@ import android.os.Bundle
import android.os.Handler
import android.support.v4.app.Fragment
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.Toolbar
import io.casey.musikcube.remote.Application
import io.casey.musikcube.remote.R
import io.casey.musikcube.remote.framework.IMixin
import io.casey.musikcube.remote.framework.MixinSet
import io.casey.musikcube.remote.framework.ViewModel
import io.casey.musikcube.remote.injection.DaggerViewComponent
import io.casey.musikcube.remote.injection.ViewComponent
import io.casey.musikcube.remote.ui.settings.constants.Prefs
import io.casey.musikcube.remote.ui.shared.activity.ITitleProvider
import io.casey.musikcube.remote.ui.shared.extension.setTitleFromIntent
import io.casey.musikcube.remote.ui.shared.mixin.ViewModelMixin
import io.reactivex.disposables.CompositeDisposable
@ -51,6 +55,9 @@ open class BaseFragment: Fragment(), ViewModel.Provider {
super.onResume()
paused = false
mixins.onResume()
if (this is ITitleProvider) {
toolbar?.setTitleFromIntent(title)
}
}
override fun onPause() {
@ -86,7 +93,13 @@ open class BaseFragment: Fragment(), ViewModel.Provider {
protected fun <T: IMixin> mixin(mixin: T): T = mixins.add(mixin)
protected fun <T: IMixin> mixin(cls: Class<out T>): T? = mixins.get(cls)
protected val extras: Bundle
val hasToolbar: Boolean
get() = this.toolbar != null
val toolbar: Toolbar?
get() = this.view?.findViewById(R.id.toolbar)
val extras: Bundle
get() = arguments ?: Bundle()
val appCompatActivity: AppCompatActivity

View File

@ -13,12 +13,10 @@ import io.casey.musikcube.remote.service.websocket.model.ITrack
import io.casey.musikcube.remote.service.websocket.model.ITrackListQueryFactory
import io.casey.musikcube.remote.ui.home.activity.MainActivity
import io.casey.musikcube.remote.ui.shared.activity.IFilterable
import io.casey.musikcube.remote.ui.shared.activity.IMenuProvider
import io.casey.musikcube.remote.ui.shared.activity.ITitleProvider
import io.casey.musikcube.remote.ui.shared.activity.ITransportObserver
import io.casey.musikcube.remote.ui.shared.extension.EXTRA_ACTIVITY_TITLE
import io.casey.musikcube.remote.ui.shared.extension.initSearchMenu
import io.casey.musikcube.remote.ui.shared.extension.setupDefaultRecyclerView
import io.casey.musikcube.remote.ui.shared.extension.showSnackbar
import io.casey.musikcube.remote.ui.shared.extension.*
import io.casey.musikcube.remote.ui.shared.fragment.BaseFragment
import io.casey.musikcube.remote.ui.shared.mixin.DataProviderMixin
import io.casey.musikcube.remote.ui.shared.mixin.ItemContextMenuMixin
@ -35,7 +33,7 @@ import io.casey.musikcube.remote.util.Strings
import io.reactivex.Observable
import io.reactivex.rxkotlin.subscribeBy
class TrackListFragment: BaseFragment(), IFilterable, ITitleProvider, ITransportObserver {
class TrackListFragment: BaseFragment(), IFilterable, ITitleProvider, ITransportObserver, IMenuProvider {
private lateinit var tracks: DefaultSlidingWindow
private lateinit var emptyView: EmptyListView
private lateinit var adapter: TrackListAdapter
@ -100,13 +98,14 @@ class TrackListFragment: BaseFragment(), IFilterable, ITitleProvider, ITransport
}))
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
inflater.inflate(R.layout.recycler_view_fragment, container, false).apply {
inflater.inflate(this.getLayoutId(), container, false).apply {
val recyclerView = findViewById<FastScrollRecyclerView>(R.id.recycler_view)
tracks = DefaultSlidingWindow(recyclerView, data.provider, queryFactory)
adapter = TrackListAdapter(tracks, eventListener, playback, prefs)
setupDefaultRecyclerView(recyclerView, adapter)
initToolbarIfNecessary(this)
emptyView = findViewById(R.id.empty_list_view)
@ -127,7 +126,7 @@ class TrackListFragment: BaseFragment(), IFilterable, ITitleProvider, ITransport
filterDebouncer.call()
}
fun createOptionsMenu(menu: Menu): Boolean {
override fun createOptionsMenu(menu: Menu): Boolean {
when (Metadata.Category.PLAYLISTS == categoryType) {
true -> appCompatActivity.menuInflater.inflate(R.menu.view_playlist_menu, menu)
false -> initSearchMenu(menu, this)
@ -135,8 +134,8 @@ class TrackListFragment: BaseFragment(), IFilterable, ITitleProvider, ITransport
return true
}
fun optionsItemSelected(item: MenuItem): Boolean =
when (item.itemId == R.id.action_edit) {
override fun optionsItemSelected(menuItem: MenuItem): Boolean =
when (menuItem.itemId == R.id.action_edit) {
true -> {
appCompatActivity.startActivityForResult(
EditPlaylistActivity.getStartIntent(

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="?attr/colorControlNormal" android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
</vector>