ui: fix liftOnScroll issues entirely
Make a hack layout that fixes the problem of the lift state not actually following the RecyclerView state. This should remove the need for all the fragile fixes for this UI idiom.
This commit is contained in:
parent
047b885dca
commit
1251af660a
8 changed files with 87 additions and 26 deletions
|
@ -78,19 +78,7 @@ class QueueDragCallback(
|
|||
)
|
||||
)
|
||||
|
||||
val result = clampedAbsVelocity * sign(viewSizeOutOfBounds.toDouble()).toInt()
|
||||
|
||||
recyclerView.post {
|
||||
// CoordinatorLayout refuses to propagate a scroll event initiated by an item scroll,
|
||||
// so we do it ourselves.
|
||||
(appBar.layoutParams as CoordinatorLayout.LayoutParams).behavior
|
||||
?.onNestedPreScroll(
|
||||
coordinator, appBar, recyclerView,
|
||||
0, result, tConsumed, 0
|
||||
)
|
||||
}
|
||||
|
||||
return result
|
||||
return clampedAbsVelocity * sign(viewSizeOutOfBounds.toDouble()).toInt()
|
||||
}
|
||||
|
||||
override fun onChildDraw(
|
||||
|
|
|
@ -107,7 +107,7 @@ class QueueFragment : Fragment() {
|
|||
lastShuffle = isShuffling
|
||||
|
||||
binding.queueRecycler.scrollToPosition(0)
|
||||
binding.queueAppbar.isLifted = false // Make sure lifted state changes.
|
||||
// binding.queueAppbar.isLifted = false // Make sure lifted state changes.
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -144,12 +144,11 @@ class SearchFragment : Fragment() {
|
|||
// TODO: Maybe find a better way to keep scroll state when the search
|
||||
// results didn't actually change.
|
||||
binding.searchRecycler.scrollToPosition(0)
|
||||
binding.searchAppbar.isLifted = false
|
||||
}
|
||||
|
||||
if (results.isEmpty()) {
|
||||
binding.searchAppbar.setExpanded(true)
|
||||
binding.searchRecycler.visibility = View.GONE
|
||||
binding.searchRecycler.visibility = View.INVISIBLE
|
||||
} else {
|
||||
binding.searchRecycler.visibility = View.VISIBLE
|
||||
}
|
||||
|
|
73
app/src/main/java/org/oxycblt/auxio/ui/LiftAppBarLayout.kt
Normal file
73
app/src/main/java/org/oxycblt/auxio/ui/LiftAppBarLayout.kt
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (c) 2021 Auxio Project
|
||||
* CobaltCoordinatorLayout.kt is part of Auxio.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.oxycblt.auxio.ui
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.ViewGroup
|
||||
import android.view.ViewTreeObserver
|
||||
import androidx.annotation.StyleRes
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.core.view.children
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.appbar.AppBarLayout
|
||||
|
||||
/**
|
||||
* An [AppBarLayout] that fixes a bug with the default implementation where the lifted state
|
||||
* will not properly respond to RecyclerView events.
|
||||
* TODO: Find a way to get the lift animation to not animate on startup.
|
||||
*/
|
||||
class LiftAppBarLayout @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
@StyleRes defStyleAttr: Int = -1
|
||||
) : AppBarLayout(context, attrs, defStyleAttr) {
|
||||
private var recycler: RecyclerView? = null
|
||||
private val tConsumed = IntArray(2)
|
||||
|
||||
private val onPreDraw = ViewTreeObserver.OnPreDrawListener {
|
||||
recycler?.let { rec ->
|
||||
val coordinator = (parent as CoordinatorLayout)
|
||||
|
||||
(layoutParams as CoordinatorLayout.LayoutParams).behavior?.onNestedPreScroll(
|
||||
coordinator, this, rec, 0, 0, tConsumed, 0
|
||||
)
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
init {
|
||||
viewTreeObserver.addOnPreDrawListener(onPreDraw)
|
||||
}
|
||||
|
||||
override fun onAttachedToWindow() {
|
||||
super.onAttachedToWindow()
|
||||
|
||||
// Assume there is one RecyclerView [Because there is]
|
||||
recycler = (parent as ViewGroup).children.firstOrNull { it is RecyclerView }
|
||||
as RecyclerView?
|
||||
}
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow()
|
||||
|
||||
viewTreeObserver.removeOnPreDrawListener(onPreDraw)
|
||||
}
|
||||
}
|
|
@ -8,7 +8,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
<org.oxycblt.auxio.ui.LiftAppBarLayout
|
||||
android:id="@+id/detail_appbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -19,7 +19,7 @@
|
|||
android:id="@+id/detail_toolbar"
|
||||
style="@style/Widget.Toolbar.Icon" />
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
</org.oxycblt.auxio.ui.LiftAppBarLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/detail_recycler"
|
||||
|
@ -27,7 +27,8 @@
|
|||
android:layout_height="match_parent"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
|
||||
tools:listitem="@layout/item_artist_header" />
|
||||
tools:listitem="@layout/item_artist_header"
|
||||
tools:layout_marginTop="56dp"/>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
</layout>
|
|
@ -12,7 +12,7 @@
|
|||
android:background="?attr/colorSurface"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
<org.oxycblt.auxio.ui.LiftAppBarLayout
|
||||
android:id="@+id/queue_appbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -26,7 +26,7 @@
|
|||
app:navigationIcon="@drawable/ic_down"
|
||||
app:title="@string/lbl_queue" />
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
</org.oxycblt.auxio.ui.LiftAppBarLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/queue_recycler"
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
<org.oxycblt.auxio.ui.LiftAppBarLayout
|
||||
android:id="@+id/search_appbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -29,7 +29,7 @@
|
|||
app:boxBackgroundMode="filled"
|
||||
app:boxStrokeColor="?attr/colorAccent"
|
||||
app:boxStrokeWidth="0dp"
|
||||
app:boxStrokeWidthFocused="2dp"
|
||||
app:boxStrokeWidthFocused="@dimen/size_stroke_large"
|
||||
app:endIconContentDescription="@string/desc_clear_search"
|
||||
app:endIconDrawable="@drawable/ic_close"
|
||||
app:endIconMode="clear_text"
|
||||
|
@ -48,7 +48,7 @@
|
|||
android:textCursorDrawable="@drawable/ui_cursor" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
</org.oxycblt.auxio.ui.LiftAppBarLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/search_recycler"
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
android:background="?attr/colorSurface"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
<org.oxycblt.auxio.ui.LiftAppBarLayout
|
||||
android:id="@+id/settings_appbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -26,7 +26,7 @@
|
|||
app:menu="@menu/menu_settings"
|
||||
app:title="@string/set_title" />
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
</org.oxycblt.auxio.ui.LiftAppBarLayout>
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/settings_list_fragment"
|
||||
|
|
Loading…
Reference in a new issue