ui: improve playback/about UIs

Make playback/about UIs follow the new liftOnScroll and edge-to-edge
idioms. This finally allows me to collapse a lot of duplicate code
into MainActivity and in general reduce code mess.
This commit is contained in:
OxygenCobalt 2021-08-30 19:53:19 -06:00
parent 1251af660a
commit 765f92ca98
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
17 changed files with 56 additions and 39 deletions

View file

@ -26,20 +26,19 @@ import android.view.WindowInsets
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate
import androidx.core.view.updatePadding
import androidx.databinding.DataBindingUtil import androidx.databinding.DataBindingUtil
import org.oxycblt.auxio.accent.Accent import org.oxycblt.auxio.accent.Accent
import org.oxycblt.auxio.databinding.ActivityMainBinding import org.oxycblt.auxio.databinding.ActivityMainBinding
import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.playback.system.PlaybackService import org.oxycblt.auxio.playback.system.PlaybackService
import org.oxycblt.auxio.settings.SettingsManager import org.oxycblt.auxio.settings.SettingsManager
import org.oxycblt.auxio.util.applyEdge
import org.oxycblt.auxio.util.isNight import org.oxycblt.auxio.util.isNight
import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.logD
/** /**
* The single [AppCompatActivity] for Auxio. * The single [AppCompatActivity] for Auxio.
* TODO: Improve edge-to-edge everywhere and phase out fitsSystemWindows.
* If you do this, then it will become trivial to merge a lot of the code [l/r padding],
* fitsSystemWindow management into this activity.
*/ */
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
private val playbackModel: PlaybackViewModel by viewModels() private val playbackModel: PlaybackViewModel by viewModels()
@ -54,7 +53,15 @@ class MainActivity : AppCompatActivity() {
) )
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setupEdgeToEdge(binding) applyEdgeToEdgeWindow(binding)
// If there are left/right insets [signalling that we are in phone landscape mode],
// we will always apply them.
binding.applyEdge { bars ->
binding.root.updatePadding(left = bars.left, right = bars.right)
}
} else {
binding.root.fitsSystemWindows = true
} }
logD("Activity created.") logD("Activity created.")
@ -105,7 +112,7 @@ class MainActivity : AppCompatActivity() {
} }
} }
private fun setupEdgeToEdge(binding: ActivityMainBinding) { private fun applyEdgeToEdgeWindow(binding: ActivityMainBinding) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
// Do modern edge to edge, which happens to be around twice the size of the // Do modern edge to edge, which happens to be around twice the size of the
// old way of doing things. Thanks android, very cool! // old way of doing things. Thanks android, very cool!

View file

@ -35,7 +35,6 @@ import org.oxycblt.auxio.util.logD
/** /**
* A wrapper around the home fragment that shows the playback fragment and controls * A wrapper around the home fragment that shows the playback fragment and controls
* the more high-level navigation features. * the more high-level navigation features.
* TODO: Re-add the nice playback slide in animation
*/ */
class MainFragment : Fragment() { class MainFragment : Fragment() {
private val playbackModel: PlaybackViewModel by activityViewModels() private val playbackModel: PlaybackViewModel by activityViewModels()
@ -52,7 +51,7 @@ class MainFragment : Fragment() {
binding.lifecycleOwner = viewLifecycleOwner binding.lifecycleOwner = viewLifecycleOwner
binding.applyEdge { bars -> binding.applyEdge { bars ->
binding.root.updatePadding(bottom = bars.bottom, left = bars.left, right = bars.right) binding.root.updatePadding(bottom = bars.bottom)
} }
// --- VIEWMODEL SETUP --- // --- VIEWMODEL SETUP ---

View file

@ -24,6 +24,7 @@ import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.SeekBar import android.widget.SeekBar
import androidx.core.view.updatePadding
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
@ -33,6 +34,7 @@ import org.oxycblt.auxio.databinding.FragmentPlaybackBinding
import org.oxycblt.auxio.detail.DetailViewModel import org.oxycblt.auxio.detail.DetailViewModel
import org.oxycblt.auxio.playback.state.LoopMode import org.oxycblt.auxio.playback.state.LoopMode
import org.oxycblt.auxio.ui.memberBinding import org.oxycblt.auxio.ui.memberBinding
import org.oxycblt.auxio.util.applyEdge
import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.logD
import org.oxycblt.auxio.util.resolveDrawable import org.oxycblt.auxio.util.resolveDrawable
import org.oxycblt.auxio.util.resolveStateList import org.oxycblt.auxio.util.resolveStateList
@ -70,6 +72,13 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
binding.playbackModel = playbackModel binding.playbackModel = playbackModel
binding.detailModel = detailModel binding.detailModel = detailModel
binding.applyEdge { bars ->
binding.root.updatePadding(
top = bars.top,
bottom = bars.bottom
)
}
binding.playbackToolbar.apply { binding.playbackToolbar.apply {
setNavigationOnClickListener { setNavigationOnClickListener {
findNavController().navigateUp() findNavController().navigateUp()

View file

@ -67,7 +67,6 @@ class QueueFragment : Fragment() {
binding.lifecycleOwner = viewLifecycleOwner binding.lifecycleOwner = viewLifecycleOwner
binding.applyEdge { bars -> binding.applyEdge { bars ->
binding.root.updatePadding(left = bars.left, right = bars.right)
binding.queueAppbar.updatePadding(top = bars.top) binding.queueAppbar.updatePadding(top = bars.top)
binding.queueRecycler.updatePadding(bottom = bars.bottom) binding.queueRecycler.updatePadding(bottom = bars.bottom)
} }
@ -107,7 +106,6 @@ class QueueFragment : Fragment() {
lastShuffle = isShuffling lastShuffle = isShuffling
binding.queueRecycler.scrollToPosition(0) binding.queueRecycler.scrollToPosition(0)
// binding.queueAppbar.isLifted = false // Make sure lifted state changes.
} }
} }

View file

@ -76,7 +76,6 @@ class SearchFragment : Fragment() {
) )
val toolbarParams = binding.searchToolbar.layoutParams as AppBarLayout.LayoutParams val toolbarParams = binding.searchToolbar.layoutParams as AppBarLayout.LayoutParams
val defaultParams = toolbarParams.scrollFlags
// --- UI SETUP -- // --- UI SETUP --

View file

@ -27,6 +27,7 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.core.view.updatePadding
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
@ -34,6 +35,7 @@ import org.oxycblt.auxio.BuildConfig
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.databinding.FragmentAboutBinding import org.oxycblt.auxio.databinding.FragmentAboutBinding
import org.oxycblt.auxio.music.MusicStore import org.oxycblt.auxio.music.MusicStore
import org.oxycblt.auxio.util.applyEdge
import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.logD
import org.oxycblt.auxio.util.showToast import org.oxycblt.auxio.util.showToast
@ -50,6 +52,11 @@ class AboutFragment : Fragment() {
val binding = FragmentAboutBinding.inflate(layoutInflater) val binding = FragmentAboutBinding.inflate(layoutInflater)
val musicStore = MusicStore.getInstance() val musicStore = MusicStore.getInstance()
binding.applyEdge { bars ->
binding.aboutAppbar.updatePadding(top = bars.top,)
binding.aboutContents.updatePadding(bottom = bars.bottom)
}
binding.aboutToolbar.setNavigationOnClickListener { binding.aboutToolbar.setNavigationOnClickListener {
findNavController().navigateUp() findNavController().navigateUp()
} }

View file

@ -55,7 +55,6 @@ class SettingsFragment : Fragment() {
} }
binding.applyEdge { bars -> binding.applyEdge { bars ->
binding.root.updatePadding(left = bars.left, right = bars.right)
binding.settingsAppbar.updatePadding(top = bars.top) binding.settingsAppbar.updatePadding(top = bars.top)
// The padding + clipToPadding method does not seem to work with a // The padding + clipToPadding method does not seem to work with a

View file

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2021 Auxio Project * Copyright (c) 2021 Auxio Project
* CobaltCoordinatorLayout.kt is part of Auxio. * LiftAppBarLayout.kt is part of Auxio.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -31,7 +31,8 @@ import com.google.android.material.appbar.AppBarLayout
/** /**
* An [AppBarLayout] that fixes a bug with the default implementation where the lifted state * An [AppBarLayout] that fixes a bug with the default implementation where the lifted state
* will not properly respond to RecyclerView events. * will not properly respond to RecyclerView events.
* TODO: Find a way to get the lift animation to not animate on startup. * FIXME: Fix issue where elevation change will always animate
* FIXME: Fix issue where expanded state does not work correctly when switching orientations
*/ */
class LiftAppBarLayout @JvmOverloads constructor( class LiftAppBarLayout @JvmOverloads constructor(
context: Context, context: Context,

View file

@ -197,7 +197,6 @@ fun View.applyEdge(onApply: (Rect) -> Unit) {
} }
} }
// Not on a version that supports edge [yet], just don't do it. // Not on a version that supports edge-to-edge [yet], don't do anything
else -> fitsSystemWindows = true
} }
} }

View file

@ -24,13 +24,11 @@
android:id="@+id/playback_layout" android:id="@+id/playback_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/colorSurface" android:background="?attr/colorSurface">
android:fitsSystemWindows="true">
<androidx.appcompat.widget.Toolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/playback_toolbar" android:id="@+id/playback_toolbar"
style="@style/Widget.Toolbar.Icon.Down" style="@style/Widget.Toolbar.Icon.Down"
android:elevation="0dp"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:menu="@menu/menu_playback" app:menu="@menu/menu_playback"

View file

@ -24,13 +24,11 @@
android:id="@+id/playback_layout" android:id="@+id/playback_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/colorSurface" android:background="?attr/colorSurface">
android:fitsSystemWindows="true">
<androidx.appcompat.widget.Toolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/playback_toolbar" android:id="@+id/playback_toolbar"
style="@style/Widget.Toolbar.Icon.Down" style="@style/Widget.Toolbar.Icon.Down"
android:elevation="0dp"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:menu="@menu/menu_playback" app:menu="@menu/menu_playback"

View file

@ -24,13 +24,11 @@
android:id="@+id/playback_layout" android:id="@+id/playback_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/colorSurface" android:background="?attr/colorSurface">
android:fitsSystemWindows="true">
<androidx.appcompat.widget.Toolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/playback_toolbar" android:id="@+id/playback_toolbar"
style="@style/Widget.Toolbar.Icon.Down" style="@style/Widget.Toolbar.Icon.Down"
android:elevation="0dp"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:menu="@menu/menu_playback" app:menu="@menu/menu_playback"

View file

@ -4,21 +4,32 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
tools:context=".settings.AboutFragment"> tools:context=".settings.AboutFragment">
<LinearLayout <androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?attr/colorSurface" android:background="?attr/colorSurface"
android:fitsSystemWindows="true"
android:orientation="vertical"> android:orientation="vertical">
<androidx.appcompat.widget.Toolbar <com.google.android.material.appbar.AppBarLayout
android:id="@+id/about_toolbar" android:id="@+id/about_appbar"
style="@style/Widget.Toolbar.Icon.Down" android:layout_width="match_parent"
app:title="@string/lbl_about" /> android:layout_height="wrap_content"
android:background="?attr/colorSurface"
app:liftOnScroll="true">
<androidx.appcompat.widget.Toolbar
android:id="@+id/about_toolbar"
style="@style/Widget.Toolbar.Icon.Down"
app:title="@string/lbl_about" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView <androidx.core.widget.NestedScrollView
android:id="@+id/about_contents"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent"
android:clipToPadding="false"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
<com.google.android.material.card.MaterialCardView <com.google.android.material.card.MaterialCardView
android:layout_width="match_parent" android:layout_width="match_parent"
@ -166,5 +177,5 @@
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView> </com.google.android.material.card.MaterialCardView>
</androidx.core.widget.NestedScrollView> </androidx.core.widget.NestedScrollView>
</LinearLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout> </layout>

View file

@ -24,7 +24,6 @@
<androidx.appcompat.widget.Toolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/home_toolbar" android:id="@+id/home_toolbar"
style="@style/Widget.Toolbar" style="@style/Widget.Toolbar"
android:elevation="0dp"
app:layout_scrollFlags="scroll|enterAlways" app:layout_scrollFlags="scroll|enterAlways"
app:menu="@menu/menu_home" app:menu="@menu/menu_home"
app:title="@string/info_app_name" /> app:title="@string/info_app_name" />

View file

@ -23,13 +23,11 @@
android:id="@+id/playback_layout" android:id="@+id/playback_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/colorSurface" android:background="?attr/colorSurface">
android:fitsSystemWindows="true">
<androidx.appcompat.widget.Toolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/playback_toolbar" android:id="@+id/playback_toolbar"
style="@style/Widget.Toolbar.Icon.Down" style="@style/Widget.Toolbar.Icon.Down"
android:elevation="0dp"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:menu="@menu/menu_playback" app:menu="@menu/menu_playback"

View file

@ -17,7 +17,6 @@
<androidx.appcompat.widget.Toolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/search_toolbar" android:id="@+id/search_toolbar"
style="@style/Widget.Toolbar.Icon" style="@style/Widget.Toolbar.Icon"
android:elevation="0dp"
app:layout_scrollFlags="scroll|enterAlways" app:layout_scrollFlags="scroll|enterAlways"
app:menu="@menu/menu_search" app:menu="@menu/menu_search"
app:title="@string/lbl_search" /> app:title="@string/lbl_search" />

View file

@ -6,8 +6,6 @@
<style name="Widget.Toolbar" parent="ThemeOverlay.MaterialComponents.ActionBar"> <style name="Widget.Toolbar" parent="ThemeOverlay.MaterialComponents.ActionBar">
<item name="android:layout_width">match_parent</item> <item name="android:layout_width">match_parent</item>
<item name="android:layout_height">?android:attr/actionBarSize</item> <item name="android:layout_height">?android:attr/actionBarSize</item>
<item name="android:background">?attr/colorSurface</item>
<item name="android:elevation">@dimen/elevation_normal</item>
<item name="popupTheme">@style/ThemeOverlay.ToolbarPopup</item> <item name="popupTheme">@style/ThemeOverlay.ToolbarPopup</item>
<item name="titleTextAppearance">@style/TextAppearance.Toolbar.Header</item> <item name="titleTextAppearance">@style/TextAppearance.Toolbar.Header</item>