mirror of
https://github.com/clangen/musikcube.git
synced 2025-03-29 19:20:28 +00:00
Working CategoryBrowseFragment, plus various cleanups to make things more Kotlinesque
This commit is contained in:
parent
04f5f2e645
commit
4e0555d13c
@ -1,7 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="io.casey.musikcube.remote" >
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="io.casey.musikcube.remote">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
@ -10,18 +11,19 @@
|
||||
<permission android:name="android.permission.MEDIA_CONTENT_CONTROL" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:allowBackup="false"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:name=".Application"
|
||||
android:usesCleartextTraffic="true"
|
||||
android:theme="@style/AppTheme" >
|
||||
android:theme="@style/AppTheme"
|
||||
tools:replace="android:allowBackup">
|
||||
|
||||
<activity android:name=".ui.home.activity.MainActivity"
|
||||
android:screenOrientation="portrait">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
@ -30,6 +32,10 @@
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize" />
|
||||
|
||||
<activity android:name=".ui.category.activity.CategoryBrowseActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize" />
|
||||
|
||||
<activity android:name=".ui.settings.activity.SettingsActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize|stateHidden" />
|
||||
@ -64,11 +70,6 @@
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize" />
|
||||
|
||||
<activity
|
||||
android:name="io.casey.musikcube.remote.ui.category.activity.CategoryBrowseActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize" />
|
||||
|
||||
<activity
|
||||
android:name="io.casey.musikcube.remote.ui.category.activity.AllCategoriesActivity"
|
||||
android:screenOrientation="portrait"
|
||||
@ -79,7 +80,9 @@
|
||||
android:label="@string/connections_title"
|
||||
android:windowSoftInputMode="adjustResize" />
|
||||
|
||||
<service android:name="io.casey.musikcube.remote.service.system.SystemService">
|
||||
<service
|
||||
android:name="io.casey.musikcube.remote.service.system.SystemService"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="io.casey.musikcube.remote.WAKE_UP" />
|
||||
<action android:name="io.casey.musikcube.remote.SHUT_DOWN" />
|
||||
|
@ -61,11 +61,9 @@ class AlbumBrowseActivity : BaseActivity(), Filterable {
|
||||
emptyView.emptyMessage = getString(R.string.empty_no_items_format, getString(R.string.browse_type_albums))
|
||||
emptyView.alternateView = recyclerView
|
||||
|
||||
transport = addTransportFragment(object: TransportFragment.OnModelChangedListener {
|
||||
override fun onChanged(fragment: TransportFragment) {
|
||||
adapter.notifyDataSetChanged()
|
||||
}
|
||||
})!!
|
||||
transport = addTransportFragment {
|
||||
adapter.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
|
@ -4,188 +4,51 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.View
|
||||
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
|
||||
import io.casey.musikcube.remote.R
|
||||
import io.casey.musikcube.remote.service.websocket.Messages
|
||||
import io.casey.musikcube.remote.service.websocket.model.ICategoryValue
|
||||
import io.casey.musikcube.remote.service.websocket.model.IDataProvider
|
||||
import io.casey.musikcube.remote.ui.albums.activity.AlbumBrowseActivity
|
||||
import io.casey.musikcube.remote.ui.category.adapter.CategoryBrowseAdapter
|
||||
import io.casey.musikcube.remote.ui.category.constant.*
|
||||
import io.casey.musikcube.remote.ui.category.constant.Category
|
||||
import io.casey.musikcube.remote.ui.category.constant.NavigationType
|
||||
import io.casey.musikcube.remote.ui.category.fragment.CategoryBrowseFragment
|
||||
import io.casey.musikcube.remote.ui.shared.activity.BaseActivity
|
||||
import io.casey.musikcube.remote.ui.shared.activity.Filterable
|
||||
import io.casey.musikcube.remote.ui.shared.extension.*
|
||||
import io.casey.musikcube.remote.ui.shared.extension.findFragment
|
||||
import io.casey.musikcube.remote.ui.shared.fragment.TransportFragment
|
||||
import io.casey.musikcube.remote.ui.shared.mixin.DataProviderMixin
|
||||
import io.casey.musikcube.remote.ui.shared.mixin.ItemContextMenuMixin
|
||||
import io.casey.musikcube.remote.ui.shared.mixin.PlaybackMixin
|
||||
import io.casey.musikcube.remote.ui.shared.view.EmptyListView
|
||||
import io.casey.musikcube.remote.ui.tracks.activity.TrackListActivity
|
||||
import io.casey.musikcube.remote.util.Debouncer
|
||||
import io.reactivex.rxkotlin.subscribeBy
|
||||
import java.lang.IllegalArgumentException
|
||||
import io.casey.musikcube.remote.service.websocket.WebSocketService.State as SocketState
|
||||
|
||||
class CategoryBrowseActivity : BaseActivity(), Filterable {
|
||||
private lateinit var adapter: CategoryBrowseAdapter
|
||||
private var navigationType: NavigationType = NavigationType.Tracks
|
||||
private var lastFilter: String? = null
|
||||
private lateinit var category: String
|
||||
private lateinit var predicateType: String
|
||||
private var predicateId: Long = -1
|
||||
private lateinit var content: CategoryBrowseFragment
|
||||
private lateinit var transport: TransportFragment
|
||||
private lateinit var emptyView: EmptyListView
|
||||
private lateinit var data: DataProviderMixin
|
||||
private lateinit var playback: PlaybackMixin
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
component.inject(this)
|
||||
data = mixin(DataProviderMixin())
|
||||
playback = mixin(PlaybackMixin())
|
||||
mixin(ItemContextMenuMixin(this, contextMenuListener))
|
||||
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
category = intent.getStringExtra(Category.Extra.CATEGORY)
|
||||
predicateType = intent.getStringExtra(Category.Extra.PREDICATE_TYPE) ?: ""
|
||||
predicateId = intent.getLongExtra(Category.Extra.PREDICATE_ID, -1)
|
||||
navigationType = NavigationType.get(intent.getIntExtra(Category.Extra.NAVIGATION_TYPE, NavigationType.Albums.ordinal))
|
||||
adapter = CategoryBrowseAdapter(adapterListener, playback, navigationType, category, prefs)
|
||||
setContentView(R.layout.fragment_with_transport_activity)
|
||||
|
||||
setContentView(R.layout.recycler_view_activity)
|
||||
setTitleFromIntent(categoryTitleString)
|
||||
|
||||
val recyclerView = findViewById<FastScrollRecyclerView>(R.id.recycler_view)
|
||||
val fab = findViewById<View>(R.id.fab)
|
||||
val fabVisible = (category == Messages.Category.PLAYLISTS)
|
||||
|
||||
emptyView = findViewById(R.id.empty_list_view)
|
||||
emptyView.capability = EmptyListView.Capability.OnlineOnly
|
||||
emptyView.emptyMessage = getString(R.string.empty_no_items_format, categoryTypeString)
|
||||
emptyView.alternateView = recyclerView
|
||||
|
||||
setupDefaultRecyclerView(recyclerView, adapter)
|
||||
setFabVisible(fabVisible, fab, recyclerView)
|
||||
enableUpNavigation()
|
||||
|
||||
findViewById<View>(R.id.fab).setOnClickListener {
|
||||
if (category == Messages.Category.PLAYLISTS) {
|
||||
mixin(ItemContextMenuMixin::class.java)?.createPlaylist()
|
||||
}
|
||||
when (savedInstanceState == null) {
|
||||
true -> createFragments()
|
||||
else -> restoreFragments()
|
||||
}
|
||||
|
||||
transport = addTransportFragment(object: TransportFragment.OnModelChangedListener {
|
||||
override fun onChanged(fragment: TransportFragment) {
|
||||
adapter.notifyDataSetChanged()
|
||||
}
|
||||
})!!
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
initObservers()
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
if (Messages.Category.PLAYLISTS != category) { /* bleh */
|
||||
initSearchMenu(menu, this)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun setFilter(filter: String) {
|
||||
this.lastFilter = filter
|
||||
this.filterDebouncer.call()
|
||||
}
|
||||
|
||||
private fun initObservers() {
|
||||
disposables.add(data.provider.observeState().subscribeBy(
|
||||
onNext = { states ->
|
||||
when (states.first) {
|
||||
IDataProvider.State.Connected -> {
|
||||
filterDebouncer.cancel()
|
||||
requery()
|
||||
}
|
||||
IDataProvider.State.Disconnected -> {
|
||||
emptyView.update(states.first, adapter.itemCount)
|
||||
}
|
||||
else -> { }
|
||||
}
|
||||
},
|
||||
onError = {
|
||||
}))
|
||||
}
|
||||
|
||||
private val categoryTypeString: String
|
||||
get() {
|
||||
Category.NAME_TO_EMPTY_TYPE[category]?.let {
|
||||
return getString(it)
|
||||
}
|
||||
return Category.toDisplayString(this, category)
|
||||
}
|
||||
|
||||
private val categoryTitleString: String
|
||||
get() {
|
||||
Category.NAME_TO_TITLE[category]?.let {
|
||||
return getString(it)
|
||||
}
|
||||
return Category.toDisplayString(this, category)
|
||||
}
|
||||
|
||||
private fun requery() {
|
||||
@Suppress("UNUSED")
|
||||
data.provider
|
||||
.getCategoryValues(category, predicateType, predicateId, lastFilter ?: "")
|
||||
.subscribeBy(
|
||||
onNext = { values -> adapter.setModel(values) },
|
||||
onError = { },
|
||||
onComplete = { emptyView.update(data.provider.state, adapter.itemCount)})
|
||||
}
|
||||
|
||||
private val filterDebouncer = object : Debouncer<String>(350) {
|
||||
override fun onDebounced(last: String?) {
|
||||
if (!isPaused()) {
|
||||
requery()
|
||||
}
|
||||
transport.modelChangedListener = {
|
||||
content.notifyTransportChanged()
|
||||
}
|
||||
}
|
||||
|
||||
private val contextMenuListener = object: ItemContextMenuMixin.EventListener() {
|
||||
override fun onPlaylistDeleted(id: Long, name: String) = requery()
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean = content.createOptionsMenu(menu)
|
||||
override fun setFilter(filter: String) = content.setFilter(filter)
|
||||
|
||||
override fun onPlaylistUpdated(id: Long, name: String) = requery()
|
||||
|
||||
override fun onPlaylistCreated(id: Long, name: String) =
|
||||
if (navigationType == NavigationType.Select) navigateToSelect(id, name) else requery()
|
||||
private fun createFragments() {
|
||||
content = CategoryBrowseFragment.create(intent)
|
||||
transport = TransportFragment.create()
|
||||
supportFragmentManager
|
||||
.beginTransaction()
|
||||
.add(R.id.content_container, content, CategoryBrowseFragment.TAG)
|
||||
.add(R.id.transport_container, transport, TransportFragment.TAG)
|
||||
.commit()
|
||||
}
|
||||
|
||||
private val adapterListener = object: CategoryBrowseAdapter.EventListener {
|
||||
override fun onItemClicked(value: ICategoryValue) {
|
||||
when (navigationType) {
|
||||
NavigationType.Albums -> navigateToAlbums(value)
|
||||
NavigationType.Tracks -> navigateToTracks(value)
|
||||
NavigationType.Select -> navigateToSelect(value.id, value.value)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActionClicked(view: View, value: ICategoryValue) {
|
||||
mixin(ItemContextMenuMixin::class.java)?.showForCategory(value, view)
|
||||
}
|
||||
}
|
||||
|
||||
private fun navigateToAlbums(entry: ICategoryValue) =
|
||||
startActivity(AlbumBrowseActivity.getStartIntent(this, category, entry))
|
||||
|
||||
private fun navigateToTracks(entry: ICategoryValue) =
|
||||
startActivity(TrackListActivity.getStartIntent(this, category, entry.id, entry.value))
|
||||
|
||||
private fun navigateToSelect(id: Long, name: String) {
|
||||
setResult(RESULT_OK, Intent()
|
||||
.putExtra(Category.Extra.CATEGORY, category)
|
||||
.putExtra(Category.Extra.ID, id)
|
||||
.putExtra(Category.Extra.NAME, name))
|
||||
finish()
|
||||
private fun restoreFragments() {
|
||||
transport = findFragment(TransportFragment.TAG)
|
||||
content = findFragment(CategoryBrowseFragment.TAG)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@ -193,33 +56,26 @@ class CategoryBrowseActivity : BaseActivity(), Filterable {
|
||||
category: String,
|
||||
predicateType: String = "",
|
||||
predicateId: Long = -1,
|
||||
predicateValue: String = ""): Intent
|
||||
{
|
||||
val intent = Intent(context, CategoryBrowseActivity::class.java)
|
||||
.putExtra(Category.Extra.CATEGORY, category)
|
||||
.putExtra(Category.Extra.PREDICATE_TYPE, predicateType)
|
||||
.putExtra(Category.Extra.PREDICATE_ID, predicateId)
|
||||
|
||||
if (predicateValue.isNotBlank() && Category.NAME_TO_RELATED_TITLE.containsKey(category)) {
|
||||
val format = Category.NAME_TO_RELATED_TITLE[category]
|
||||
when (format) {
|
||||
null -> throw IllegalArgumentException("unknown category $category")
|
||||
else -> intent.putExtra(EXTRA_ACTIVITY_TITLE, context.getString(format, predicateValue))
|
||||
}
|
||||
predicateValue: String = ""): Intent =
|
||||
Intent(context, CategoryBrowseActivity::class.java).apply {
|
||||
putExtra(
|
||||
Category.Extra.FRAGMENT_ARGUMENTS,
|
||||
CategoryBrowseFragment.arguments(
|
||||
context,
|
||||
category,
|
||||
predicateType,
|
||||
predicateId,
|
||||
predicateValue))
|
||||
}
|
||||
|
||||
return intent
|
||||
}
|
||||
|
||||
fun getStartIntent(context: Context,
|
||||
category: String,
|
||||
navigationType: NavigationType,
|
||||
title: String = ""): Intent
|
||||
{
|
||||
return Intent(context, CategoryBrowseActivity::class.java)
|
||||
.putExtra(Category.Extra.CATEGORY, category)
|
||||
.putExtra(Category.Extra.NAVIGATION_TYPE, navigationType.ordinal)
|
||||
.putExtra(Category.Extra.TITLE, title)
|
||||
}
|
||||
title: String = ""): Intent =
|
||||
Intent(context, CategoryBrowseActivity::class.java).apply {
|
||||
putExtra(
|
||||
Category.Extra.FRAGMENT_ARGUMENTS,
|
||||
CategoryBrowseFragment.arguments(category, navigationType, title))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -53,6 +53,7 @@ object Category {
|
||||
const val PREDICATE_ID = "extra_predicate_id"
|
||||
const val NAVIGATION_TYPE = "extra_navigation_type"
|
||||
const val TITLE = "extra_title"
|
||||
const val FRAGMENT_ARGUMENTS = "fragment_arguments"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,10 +68,10 @@ class CategoryBrowseFragment: BaseFragment(), Filterable {
|
||||
adapter = CategoryBrowseAdapter(adapterListener, playback, navigationType, category, prefs)
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
rootView = inflater.inflate(R.layout.recycler_view_activity, container, false)
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? =
|
||||
inflater.inflate(R.layout.recycler_view_fragment, container, false).apply {
|
||||
this@CategoryBrowseFragment.rootView = this
|
||||
|
||||
rootView.apply {
|
||||
val recyclerView = findViewById<FastScrollRecyclerView>(R.id.recycler_view)
|
||||
val fab = findViewById<View>(R.id.fab)
|
||||
val fabVisible = (category == Messages.Category.PLAYLISTS)
|
||||
@ -91,9 +91,6 @@ class CategoryBrowseFragment: BaseFragment(), Filterable {
|
||||
setFabVisible(fabVisible, fab, recyclerView)
|
||||
}
|
||||
|
||||
return rootView
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
initObservers()
|
||||
@ -112,6 +109,9 @@ class CategoryBrowseFragment: BaseFragment(), Filterable {
|
||||
return true
|
||||
}
|
||||
|
||||
fun notifyTransportChanged() =
|
||||
adapter.notifyDataSetChanged()
|
||||
|
||||
private fun initObservers() {
|
||||
disposables.add(data.provider.observeState().subscribeBy(
|
||||
onNext = { states ->
|
||||
@ -196,24 +196,45 @@ class CategoryBrowseFragment: BaseFragment(), Filterable {
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun create(context: Context,
|
||||
category: String,
|
||||
predicateType: String = "",
|
||||
predicateId: Long = -1,
|
||||
predicateValue: String = ""): CategoryBrowseFragment =
|
||||
const val TAG = "CategoryBrowseFragment"
|
||||
|
||||
fun create(intent: Intent?): CategoryBrowseFragment {
|
||||
if (intent == null) {
|
||||
throw IllegalArgumentException("invalid intent")
|
||||
}
|
||||
return create(intent.getBundleExtra(Category.Extra.FRAGMENT_ARGUMENTS))
|
||||
}
|
||||
|
||||
fun create(arguments: Bundle): CategoryBrowseFragment =
|
||||
CategoryBrowseFragment().apply {
|
||||
this.arguments = Bundle().apply {
|
||||
putString(Category.Extra.CATEGORY, category)
|
||||
putString(Category.Extra.PREDICATE_TYPE, predicateType)
|
||||
putLong(Category.Extra.PREDICATE_ID, predicateId)
|
||||
if (predicateValue.isNotBlank() && Category.NAME_TO_RELATED_TITLE.containsKey(category)) {
|
||||
val format = Category.NAME_TO_RELATED_TITLE[category]
|
||||
when (format) {
|
||||
null -> throw IllegalArgumentException("unknown category $category")
|
||||
else -> putString(EXTRA_ACTIVITY_TITLE, context.getString(format, predicateValue))
|
||||
}
|
||||
this.arguments = arguments
|
||||
}
|
||||
|
||||
fun arguments(context: Context,
|
||||
category: String,
|
||||
predicateType: String = "",
|
||||
predicateId: Long = -1,
|
||||
predicateValue: String = ""): Bundle =
|
||||
Bundle().apply {
|
||||
putString(Category.Extra.CATEGORY, category)
|
||||
putString(Category.Extra.PREDICATE_TYPE, predicateType)
|
||||
putLong(Category.Extra.PREDICATE_ID, predicateId)
|
||||
if (predicateValue.isNotBlank() && Category.NAME_TO_RELATED_TITLE.containsKey(category)) {
|
||||
val format = Category.NAME_TO_RELATED_TITLE[category]
|
||||
when (format) {
|
||||
null -> throw IllegalArgumentException("unknown category $category")
|
||||
else -> putString(EXTRA_ACTIVITY_TITLE, context.getString(format, predicateValue))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun arguments(category: String,
|
||||
navigationType: NavigationType,
|
||||
title: String = ""): Bundle =
|
||||
Bundle().apply {
|
||||
putString(Category.Extra.CATEGORY, category)
|
||||
putInt(Category.Extra.NAVIGATION_TYPE, navigationType.ordinal)
|
||||
putString(Category.Extra.TITLE, title)
|
||||
}
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@ import android.content.SharedPreferences
|
||||
import android.support.design.widget.Snackbar
|
||||
import android.support.v4.app.DialogFragment
|
||||
import android.support.v4.app.Fragment
|
||||
import android.support.v4.app.FragmentManager
|
||||
import android.support.v4.content.ContextCompat
|
||||
import android.support.v4.view.MenuItemCompat
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
@ -28,6 +29,7 @@ import io.casey.musikcube.remote.ui.shared.activity.Filterable
|
||||
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
|
||||
import java.lang.IllegalArgumentException
|
||||
|
||||
const val EXTRA_ACTIVITY_TITLE = "extra_title"
|
||||
|
||||
@ -65,26 +67,25 @@ fun AppCompatActivity.enableUpNavigation() {
|
||||
}
|
||||
|
||||
fun AppCompatActivity.addTransportFragment(
|
||||
listener: TransportFragment.OnModelChangedListener? = null): TransportFragment?
|
||||
listener: ((TransportFragment) -> Unit)? = null): TransportFragment
|
||||
{
|
||||
val root = findViewById<View>(android.R.id.content)
|
||||
if (root != null) {
|
||||
if (root.findViewById<View>(R.id.transport_container) != null) {
|
||||
val fragment = TransportFragment.newInstance()
|
||||
val fragment = TransportFragment.create()
|
||||
|
||||
this.supportFragmentManager
|
||||
.beginTransaction()
|
||||
.add(R.id.transport_container, fragment, TransportFragment.TAG)
|
||||
.commit()
|
||||
.beginTransaction()
|
||||
.add(R.id.transport_container, fragment, TransportFragment.TAG)
|
||||
.commit()
|
||||
|
||||
fragment.modelChangedListener = listener
|
||||
return fragment
|
||||
}
|
||||
}
|
||||
return null
|
||||
throw IllegalArgumentException("could not find content view")
|
||||
}
|
||||
|
||||
|
||||
fun AppCompatActivity.setTitleFromIntent(defaultId: Int) =
|
||||
this.setTitleFromIntent(getString(defaultId))
|
||||
|
||||
@ -274,4 +275,12 @@ fun titleEllipsizeMode(prefs: SharedPreferences): TextUtils.TruncateAt {
|
||||
1 -> TextUtils.TruncateAt.MIDDLE
|
||||
else -> TextUtils.TruncateAt.END
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <reified T> FragmentManager.find(tag: String): T {
|
||||
return findFragmentByTag(tag) as T
|
||||
}
|
||||
|
||||
inline fun <reified T> AppCompatActivity.findFragment(tag: String): T {
|
||||
return this.supportFragmentManager.find(tag)
|
||||
}
|
@ -23,9 +23,7 @@ class TransportFragment: BaseFragment() {
|
||||
lateinit var playback: PlaybackMixin
|
||||
private set
|
||||
|
||||
interface OnModelChangedListener {
|
||||
fun onChanged(fragment: TransportFragment)
|
||||
}
|
||||
var modelChangedListener: ((TransportFragment) -> Unit)? = null
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View?
|
||||
@ -46,8 +44,6 @@ class TransportFragment: BaseFragment() {
|
||||
rebindUi()
|
||||
}
|
||||
|
||||
var modelChangedListener: OnModelChangedListener? = null
|
||||
|
||||
private fun bindEventHandlers() {
|
||||
this.title = this.rootView.findViewById(R.id.track_title)
|
||||
this.title.isClickable = false
|
||||
@ -119,11 +115,11 @@ class TransportFragment: BaseFragment() {
|
||||
|
||||
private val playbackListener: () -> Unit = {
|
||||
rebindUi()
|
||||
modelChangedListener?.onChanged(this@TransportFragment)
|
||||
modelChangedListener?.invoke(this@TransportFragment)
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val TAG = "TransportFragment"
|
||||
fun newInstance(): TransportFragment = TransportFragment()
|
||||
fun create(): TransportFragment = TransportFragment()
|
||||
}
|
||||
}
|
||||
|
@ -82,10 +82,9 @@ class TrackListActivity : BaseActivity(), Filterable {
|
||||
|
||||
tracks.setOnMetadataLoadedListener(slidingWindowListener)
|
||||
|
||||
transport = addTransportFragment(object: TransportFragment.OnModelChangedListener {
|
||||
override fun onChanged(fragment: TransportFragment) =
|
||||
adapter.notifyDataSetChanged()
|
||||
})!!
|
||||
transport = addTransportFragment {
|
||||
adapter.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
|
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/content_container"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="0dp"
|
||||
android:layout_width="match_parent" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/transport_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:elevation="4dp"/>
|
||||
|
||||
</LinearLayout>
|
@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
|
||||
android:id="@+id/recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:fastScrollAutoHide="true"
|
||||
app:fastScrollAutoHideDelay="1500"
|
||||
app:fastScrollThumbColor="@color/color_accent" />
|
||||
|
||||
<io.casey.musikcube.remote.ui.shared.view.EmptyListView
|
||||
android:id="@+id/empty_list_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<android.support.design.widget.FloatingActionButton
|
||||
android:id="@+id/fab"
|
||||
android:layout_gravity="bottom|right"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/fab_padding"
|
||||
android:src="@drawable/ic_fab_add"
|
||||
android:scaleType="center"
|
||||
android:elevation="6dp"
|
||||
android:visibility="gone"
|
||||
app:backgroundTint="@color/color_primary"
|
||||
app:fabSize="mini"
|
||||
app:rippleColor="?colorAccent"/>
|
||||
|
||||
</FrameLayout>
|
Loading…
x
Reference in New Issue
Block a user