playback: band-aid scroll position confusion
Band-aid an issue where the scroll position of any RecyclerView in a PlaybackBarLayout would get consfused because while the main view was present, the fragment was not inflated yet so that it would not show. This is [kindof] fixed by moving the fragment instantiation to the view initialization. However, sometimes the fragment might still not be inflated. The fragment will likely be replaced with a view eventually.
This commit is contained in:
parent
e779698746
commit
ae39054b63
2 changed files with 61 additions and 43 deletions
|
@ -22,6 +22,7 @@ import android.content.Context
|
||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
import android.graphics.Insets
|
import android.graphics.Insets
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
import android.os.Parcelable
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
@ -44,6 +45,13 @@ import org.oxycblt.auxio.util.systemBarsCompat
|
||||||
* properly. The mechanism is mostly inspired by Material Files' PersistentBarLayout, however
|
* properly. The mechanism is mostly inspired by Material Files' PersistentBarLayout, however
|
||||||
* this class was primarily written by me and I plan to expand this layout to become part of
|
* this class was primarily written by me and I plan to expand this layout to become part of
|
||||||
* the playback navigation process.
|
* the playback navigation process.
|
||||||
|
*
|
||||||
|
* TODO: Migrate CompactPlaybackFragment to a view. This is okay, as updates can be delivered
|
||||||
|
* via MainFragment and it would fix the issue where the actual layout won't measure until
|
||||||
|
* the fragment is shown.
|
||||||
|
* TODO: Implement animation
|
||||||
|
* TODO: Implement the swipe-up behavior. This needs to occur, as the way the main fragment
|
||||||
|
* saves state results in'
|
||||||
*/
|
*/
|
||||||
class PlaybackBarLayout @JvmOverloads constructor(
|
class PlaybackBarLayout @JvmOverloads constructor(
|
||||||
context: Context,
|
context: Context,
|
||||||
|
@ -74,22 +82,14 @@ class PlaybackBarLayout @JvmOverloads constructor(
|
||||||
fillColor = ColorStateList.valueOf(R.attr.colorSurface.resolveAttr(context))
|
fillColor = ColorStateList.valueOf(R.attr.colorSurface.resolveAttr(context))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun onAttachedToWindow() {
|
if (!isInEditMode) {
|
||||||
super.onAttachedToWindow()
|
(context as AppCompatActivity).supportFragmentManager.apply {
|
||||||
|
this
|
||||||
if (isInEditMode) {
|
.beginTransaction()
|
||||||
return
|
.replace(R.id.main_playback, playbackFragment)
|
||||||
}
|
.commit()
|
||||||
|
}
|
||||||
// By default, using a FragmentContainerView in this view will result in
|
|
||||||
// the fragment disappearing on a recreate. Who knows why.
|
|
||||||
(context as AppCompatActivity).supportFragmentManager.apply {
|
|
||||||
this
|
|
||||||
.beginTransaction()
|
|
||||||
.replace(R.id.main_playback, playbackFragment)
|
|
||||||
.commit()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,6 +107,8 @@ class PlaybackBarLayout @JvmOverloads constructor(
|
||||||
val barHeightSpec = getChildMeasureSpec(heightMeasureSpec, 0, barParams.height)
|
val barHeightSpec = getChildMeasureSpec(heightMeasureSpec, 0, barParams.height)
|
||||||
barLayout.measure(barWidthSpec, barHeightSpec)
|
barLayout.measure(barWidthSpec, barHeightSpec)
|
||||||
|
|
||||||
|
updateWindowInsets()
|
||||||
|
|
||||||
val barHeightAdjusted = (barLayout.measuredHeight * barParams.offset).toInt()
|
val barHeightAdjusted = (barLayout.measuredHeight * barParams.offset).toInt()
|
||||||
|
|
||||||
val contentWidth = measuredWidth
|
val contentWidth = measuredWidth
|
||||||
|
@ -124,8 +126,6 @@ class PlaybackBarLayout @JvmOverloads constructor(
|
||||||
child.measure(childWidthSpec, childHeightSpec)
|
child.measure(childWidthSpec, childHeightSpec)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateWindowInsets()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
|
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
|
||||||
|
@ -154,9 +154,9 @@ class PlaybackBarLayout @JvmOverloads constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun dispatchApplyWindowInsets(insets: WindowInsets): WindowInsets {
|
override fun dispatchApplyWindowInsets(insets: WindowInsets): WindowInsets {
|
||||||
lastInsets = insets
|
|
||||||
|
|
||||||
barLayout.updatePadding(bottom = insets.systemBarsCompat.bottom)
|
barLayout.updatePadding(bottom = insets.systemBarsCompat.bottom)
|
||||||
|
|
||||||
|
lastInsets = insets
|
||||||
updateWindowInsets()
|
updateWindowInsets()
|
||||||
|
|
||||||
return insets
|
return insets
|
||||||
|
@ -171,27 +171,23 @@ class PlaybackBarLayout @JvmOverloads constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun mutateInsets(insets: WindowInsets): WindowInsets {
|
private fun mutateInsets(insets: WindowInsets): WindowInsets {
|
||||||
if (barLayout.isVisible) {
|
val barParams = barLayout.layoutParams as LayoutParams
|
||||||
val barParams = barLayout.layoutParams as LayoutParams
|
val childConsumedInset = (barLayout.measuredHeight * barParams.offset).toInt()
|
||||||
val childConsumedInset = (barLayout.measuredHeight * barParams.offset).toInt()
|
|
||||||
|
|
||||||
logD(childConsumedInset)
|
val bars = insets.systemBarsCompat
|
||||||
|
|
||||||
val bars = insets.systemBarsCompat
|
// TODO: Q support
|
||||||
|
when {
|
||||||
// TODO: Q support
|
Build.VERSION.SDK_INT >= Build.VERSION_CODES.R -> {
|
||||||
when {
|
return WindowInsets.Builder(insets)
|
||||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.R -> {
|
.setInsets(
|
||||||
return WindowInsets.Builder(insets)
|
WindowInsets.Type.systemBars(),
|
||||||
.setInsets(
|
Insets.of(
|
||||||
WindowInsets.Type.systemBars(),
|
bars.left, bars.top,
|
||||||
Insets.of(
|
bars.right, (bars.bottom - childConsumedInset).coerceAtLeast(0)
|
||||||
bars.left, bars.top,
|
|
||||||
bars.right, (bars.bottom - childConsumedInset).coerceAtLeast(0)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
.build()
|
)
|
||||||
}
|
.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,13 +195,35 @@ class PlaybackBarLayout @JvmOverloads constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun showBar() {
|
fun showBar() {
|
||||||
(barLayout.layoutParams as LayoutParams).offset = 1f
|
val barParams = barLayout.layoutParams as LayoutParams
|
||||||
updateWindowInsets()
|
|
||||||
|
if (barParams.offset == 1f) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
barParams.offset = 1f
|
||||||
|
|
||||||
|
if (isLaidOut) {
|
||||||
|
updateWindowInsets()
|
||||||
|
}
|
||||||
|
|
||||||
|
invalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hideBar() {
|
fun hideBar() {
|
||||||
(barLayout.layoutParams as LayoutParams).offset = 0f
|
val barParams = barLayout.layoutParams as LayoutParams
|
||||||
updateWindowInsets()
|
|
||||||
|
if (barParams.offset == 0f) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
barParams.offset = 0f
|
||||||
|
|
||||||
|
if (isLaidOut) {
|
||||||
|
updateWindowInsets()
|
||||||
|
}
|
||||||
|
|
||||||
|
invalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- LAYOUT PARAMS ---
|
// --- LAYOUT PARAMS ---
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
tools:context=".detail.DetailFragment">
|
tools:context=".detail.DetailFragment">
|
||||||
|
|
||||||
<org.oxycblt.auxio.playback.PlaybackBarLayout
|
<FrameLayout
|
||||||
android:id="@+id/bar_layout"
|
android:id="@+id/bar_layout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
@ -38,5 +38,5 @@
|
||||||
tools:listitem="@layout/item_detail" />
|
tools:listitem="@layout/item_detail" />
|
||||||
|
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
</org.oxycblt.auxio.playback.PlaybackBarLayout>
|
</FrameLayout>
|
||||||
</layout>
|
</layout>
|
Loading…
Reference in a new issue