ui: add edge-to-edge on bar-dependent fragments
Add edge-to-edge on the Home, Detail, and Search fragments. This solution is not ideal at all, relying on viewModel state to make sure that the padding is only applied when the playback bar is not present. However, it works. I'll likely replace it with a better layout once I can figure out how similar layouts like Material Files' PersistentBarLyout work.
This commit is contained in:
parent
e01816a1dc
commit
9030de7774
5 changed files with 45 additions and 14 deletions
|
@ -36,6 +36,7 @@ import org.oxycblt.auxio.playback.PlaybackViewModel
|
|||
import org.oxycblt.auxio.ui.SortMode
|
||||
import org.oxycblt.auxio.ui.memberBinding
|
||||
import org.oxycblt.auxio.util.applyEdge
|
||||
import org.oxycblt.auxio.util.applyEdgeRespectingBar
|
||||
import org.oxycblt.auxio.util.isLandscape
|
||||
|
||||
/**
|
||||
|
@ -52,6 +53,8 @@ abstract class DetailFragment : Fragment() {
|
|||
binding.detailAppbar.updatePadding(top = bars.top)
|
||||
}
|
||||
|
||||
binding.detailRecycler.applyEdgeRespectingBar(playbackModel, viewLifecycleOwner)
|
||||
|
||||
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, callback)
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.oxycblt.auxio.home.HomeViewModel
|
|||
import org.oxycblt.auxio.music.BaseModel
|
||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||
import org.oxycblt.auxio.ui.memberBinding
|
||||
import org.oxycblt.auxio.util.applyEdgeRespectingBar
|
||||
import org.oxycblt.auxio.util.applySpans
|
||||
import org.oxycblt.auxio.util.resolveDrawable
|
||||
|
||||
|
@ -73,6 +74,7 @@ abstract class HomeListFragment : Fragment() {
|
|||
adapter = homeAdapter
|
||||
setHasFixedSize(true)
|
||||
applySpans()
|
||||
applyEdgeRespectingBar(playbackModel, viewLifecycleOwner)
|
||||
}
|
||||
|
||||
// Make sure that this RecyclerView has data before startup
|
||||
|
|
|
@ -43,6 +43,7 @@ import org.oxycblt.auxio.playback.PlaybackViewModel
|
|||
import org.oxycblt.auxio.ui.DisplayMode
|
||||
import org.oxycblt.auxio.ui.newMenu
|
||||
import org.oxycblt.auxio.util.applyEdge
|
||||
import org.oxycblt.auxio.util.applyEdgeRespectingBar
|
||||
import org.oxycblt.auxio.util.applySpans
|
||||
import org.oxycblt.auxio.util.getSystemServiceSafe
|
||||
import org.oxycblt.auxio.util.logD
|
||||
|
@ -126,6 +127,8 @@ class SearchFragment : Fragment() {
|
|||
applySpans { pos ->
|
||||
searchAdapter.currentList[pos] is Header
|
||||
}
|
||||
|
||||
applyEdgeRespectingBar(playbackModel, viewLifecycleOwner)
|
||||
}
|
||||
|
||||
// --- VIEWMODEL SETUP ---
|
||||
|
|
|
@ -32,12 +32,14 @@ import androidx.annotation.ColorInt
|
|||
import androidx.annotation.ColorRes
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.updatePadding
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import com.google.android.material.appbar.AppBarLayout
|
||||
import com.google.android.material.shape.MaterialShapeDrawable
|
||||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||
|
||||
/**
|
||||
* Apply a [MaterialShapeDrawable] to this view, automatically initializing the elevation overlay
|
||||
|
@ -140,19 +142,6 @@ fun @receiver:AttrRes Int.resolveAttr(context: Context): Int {
|
|||
return color.resolveColor(context)
|
||||
}
|
||||
|
||||
/**
|
||||
* Make this [AppBarLayout] fade a scrolling [view] out when it collapses.
|
||||
* This is mostly because I am unable to figure out how to get a collapsing view not
|
||||
* to draw under the status bar in edge-to-edge mode.
|
||||
*/
|
||||
fun AppBarLayout.makeScrollingViewFade(view: View) {
|
||||
addOnOffsetChangedListener(
|
||||
AppBarLayout.OnOffsetChangedListener { _, verticalOffset ->
|
||||
view.alpha = (view.height + verticalOffset) / view.height.toFloat()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply edge-to-edge tweaks to the root of a [ViewBinding].
|
||||
* @param onApply What to do when the system bar insets are provided
|
||||
|
@ -197,3 +186,36 @@ fun View.applyEdge(onApply: (Rect) -> Unit) {
|
|||
// Not on a version that supports edge-to-edge [yet], don't do anything
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stopgap measure to make edge-to-edge work on views that also have a playback bar.
|
||||
* The issue is that while we can apply padding initially, the padding will still be applied
|
||||
* when the bar is shown, which is very ungood. We mitigate this by just checking the song state
|
||||
* and removing the padding if it isnt available, which works okayish. I think Material Files has
|
||||
* a better implementation of the same fix however, so once I'm able to hack that layout into
|
||||
* Auxio things should be better.
|
||||
*/
|
||||
fun RecyclerView.applyEdgeRespectingBar(
|
||||
playbackModel: PlaybackViewModel,
|
||||
viewLifecycleOwner: LifecycleOwner
|
||||
) {
|
||||
var bottomPadding = 0
|
||||
|
||||
applyEdge {
|
||||
bottomPadding = it.bottom
|
||||
|
||||
if (playbackModel.song.value == null) {
|
||||
updatePadding(bottom = bottomPadding)
|
||||
} else {
|
||||
updatePadding(bottom = 0)
|
||||
}
|
||||
}
|
||||
|
||||
playbackModel.song.observe(viewLifecycleOwner) { song ->
|
||||
if (song == null) {
|
||||
updatePadding(bottom = bottomPadding)
|
||||
} else {
|
||||
updatePadding(bottom = 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
android:id="@+id/search_recycler"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
|
||||
tools:listitem="@layout/item_song" />
|
||||
|
|
Loading…
Reference in a new issue