From 46473ceff94d735f30875abcd05eea2f17500cd1 Mon Sep 17 00:00:00 2001 From: OxygenCobalt Date: Mon, 8 Aug 2022 16:09:17 -0600 Subject: [PATCH] ui: update transitions Update transitions in the home fragment to X-axis. I noticed a visual issue in the detail transition in the existing version stemming from how the main fragment's drawing is clipped by the bottom sheet, resulting in a less-than-ideal Z-axis transition. While I wanted to fix this by attempting to switch to inset based bottom sheet management, I still need to wait for more changes in order to successfully pull that off, and hence I'll be reverting it soon. Moving these transitions to X-axis prevents this visual issue while still being roughly semantically similar. --- CHANGELOG.md | 4 +- .../java/org/oxycblt/auxio/MainActivity.kt | 2 + .../auxio/detail/AlbumDetailFragment.kt | 8 ++-- .../auxio/detail/ArtistDetailFragment.kt | 8 ++-- .../auxio/detail/GenreDetailFragment.kt | 8 ++-- .../org/oxycblt/auxio/home/HomeFragment.kt | 40 +++++++++++++++++-- .../auxio/playback/PlaybackSheetBehavior.kt | 3 -- .../oxycblt/auxio/search/SearchFragment.kt | 9 ++--- .../org/oxycblt/auxio/settings/Settings.kt | 6 +-- .../auxio/ui/recycler/AuxioRecyclerView.kt | 10 ++--- .../auxio/ui/recycler/DialogRecyclerView.kt | 1 - app/src/main/res/layout/fragment_about.xml | 1 + app/src/main/res/layout/fragment_detail.xml | 1 + app/src/main/res/layout/fragment_home.xml | 1 + app/src/main/res/layout/fragment_main.xml | 1 + app/src/main/res/layout/fragment_search.xml | 1 + app/src/main/res/layout/fragment_settings.xml | 1 + app/src/main/res/values/styles_ui.xml | 2 +- 18 files changed, 67 insertions(+), 40 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 821a75dd6..cc96f903b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,8 @@ ## dev -#### What's Improved -- Improved bottom sheet code to prevent clipping issues +#### What's Changed +- Use X-axis transitions instead of Z-axis (Avoids visual clipping) #### What's Fixed - Fixed incorrect font being used in the queue title diff --git a/app/src/main/java/org/oxycblt/auxio/MainActivity.kt b/app/src/main/java/org/oxycblt/auxio/MainActivity.kt index 05fdf113a..fbb081c44 100644 --- a/app/src/main/java/org/oxycblt/auxio/MainActivity.kt +++ b/app/src/main/java/org/oxycblt/auxio/MainActivity.kt @@ -44,6 +44,8 @@ import org.oxycblt.auxio.util.systemBarInsetsCompat * * TODO: Add multi-select * + * TODO: Remove asterisk imports + * * @author OxygenCobalt */ class MainActivity : AppCompatActivity() { diff --git a/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt b/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt index ade43f324..83d21a4d7 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt @@ -68,10 +68,10 @@ class AlbumDetailFragment : override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true) - returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false) - exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true) - reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false) + enterTransition = MaterialSharedAxis(MaterialSharedAxis.X, true) + returnTransition = MaterialSharedAxis(MaterialSharedAxis.X, false) + exitTransition = MaterialSharedAxis(MaterialSharedAxis.X, true) + reenterTransition = MaterialSharedAxis(MaterialSharedAxis.X, false) } override fun onCreateBinding(inflater: LayoutInflater) = FragmentDetailBinding.inflate(inflater) diff --git a/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt b/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt index 4cb2f0424..0fd760e31 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt @@ -63,10 +63,10 @@ class ArtistDetailFragment : override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true) - returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false) - exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true) - reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false) + enterTransition = MaterialSharedAxis(MaterialSharedAxis.X, true) + returnTransition = MaterialSharedAxis(MaterialSharedAxis.X, false) + exitTransition = MaterialSharedAxis(MaterialSharedAxis.X, true) + reenterTransition = MaterialSharedAxis(MaterialSharedAxis.X, false) } override fun onCreateBinding(inflater: LayoutInflater) = FragmentDetailBinding.inflate(inflater) diff --git a/app/src/main/java/org/oxycblt/auxio/detail/GenreDetailFragment.kt b/app/src/main/java/org/oxycblt/auxio/detail/GenreDetailFragment.kt index 5342ef72f..e287fd0c8 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/GenreDetailFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/GenreDetailFragment.kt @@ -64,10 +64,10 @@ class GenreDetailFragment : override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true) - returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false) - exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true) - reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false) + enterTransition = MaterialSharedAxis(MaterialSharedAxis.X, true) + returnTransition = MaterialSharedAxis(MaterialSharedAxis.X, false) + exitTransition = MaterialSharedAxis(MaterialSharedAxis.X, true) + reenterTransition = MaterialSharedAxis(MaterialSharedAxis.X, false) } override fun onCreateBinding(inflater: LayoutInflater) = FragmentDetailBinding.inflate(inflater) diff --git a/app/src/main/java/org/oxycblt/auxio/home/HomeFragment.kt b/app/src/main/java/org/oxycblt/auxio/home/HomeFragment.kt index 82226f2c6..2485e5654 100644 --- a/app/src/main/java/org/oxycblt/auxio/home/HomeFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/home/HomeFragment.kt @@ -39,6 +39,7 @@ import com.google.android.material.tabs.TabLayoutMediator import com.google.android.material.transition.MaterialSharedAxis import java.lang.reflect.Field import kotlin.math.abs +import org.oxycblt.auxio.BuildConfig import org.oxycblt.auxio.R import org.oxycblt.auxio.databinding.FragmentHomeBinding import org.oxycblt.auxio.home.list.AlbumListFragment @@ -79,10 +80,17 @@ class HomeFragment : ViewBindingFragment(), Toolbar.OnMenuI override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true) - returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false) - exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true) - reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false) + + if (savedInstanceState != null) { + // Orientation change will wipe whatever transition we were using prior, which will + // result in no transition when the user navigates back. Make sure we re-initialize + // our transitions. + if (savedInstanceState.getBoolean(KEY_INIT_WITH_SEARCH_TRANSITIONS)) { + initSearchTransitions() + } else { + initDetailTransitions() + } + } } override fun onCreateBinding(inflater: LayoutInflater) = FragmentHomeBinding.inflate(inflater) @@ -144,6 +152,11 @@ class HomeFragment : ViewBindingFragment(), Toolbar.OnMenuI collect(navModel.exploreNavigationItem, ::handleNavigation) } + override fun onSaveInstanceState(outState: Bundle) { + outState.putBoolean(KEY_INIT_WITH_SEARCH_TRANSITIONS, enterTransition is MaterialSharedAxis) + super.onSaveInstanceState(outState) + } + override fun onDestroyBinding(binding: FragmentHomeBinding) { super.onDestroyBinding(binding) binding.homeToolbar.setOnMenuItemClickListener(null) @@ -153,6 +166,7 @@ class HomeFragment : ViewBindingFragment(), Toolbar.OnMenuI when (item.itemId) { R.id.action_search -> { logD("Navigating to search") + initSearchTransitions() findNavController().navigate(HomeFragmentDirections.actionShowSearch()) } R.id.action_settings -> { @@ -364,9 +378,25 @@ class HomeFragment : ViewBindingFragment(), Toolbar.OnMenuI else -> return } + initDetailTransitions() + findNavController().navigate(action) } + private fun initSearchTransitions() { + enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true) + returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false) + exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true) + reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false) + } + + private fun initDetailTransitions() { + enterTransition = MaterialSharedAxis(MaterialSharedAxis.X, true) + returnTransition = MaterialSharedAxis(MaterialSharedAxis.X, false) + exitTransition = MaterialSharedAxis(MaterialSharedAxis.X, true) + reenterTransition = MaterialSharedAxis(MaterialSharedAxis.X, false) + } + /** * By default, ViewPager2's sensitivity is high enough to result in vertical scroll events being * registered as horizontal scroll events. Reflect into the internal recyclerview and change the @@ -405,5 +435,7 @@ class HomeFragment : ViewBindingFragment(), Toolbar.OnMenuI lazyReflectedField(ViewPager2::class, "mRecyclerView") private val VIEW_PAGER_TOUCH_SLOP_FIELD: Field by lazyReflectedField(RecyclerView::class, "mTouchSlop") + private const val KEY_INIT_WITH_SEARCH_TRANSITIONS = + BuildConfig.APPLICATION_ID + ".key.INIT_WITH_SEARCH_TRANSITIONS" } } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackSheetBehavior.kt b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackSheetBehavior.kt index d614fb12e..4ecb45c67 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackSheetBehavior.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackSheetBehavior.kt @@ -55,9 +55,6 @@ class PlaybackSheetBehavior(context: Context, attributeSet: AttributeS init { isHideable = true - if (Settings(context).roundMode) { - sheetBackgroundDrawable.setCornerSize(context.getDimen(R.dimen.size_corners_medium)) - } } // Hack around issue where the playback sheet will try to intercept nested scrolling events diff --git a/app/src/main/java/org/oxycblt/auxio/search/SearchFragment.kt b/app/src/main/java/org/oxycblt/auxio/search/SearchFragment.kt index 80f7f1a8a..549265919 100644 --- a/app/src/main/java/org/oxycblt/auxio/search/SearchFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/search/SearchFragment.kt @@ -28,7 +28,6 @@ import androidx.core.view.postDelayed import androidx.core.widget.addTextChangedListener import androidx.fragment.app.Fragment import androidx.navigation.fragment.findNavController -import com.google.android.material.transition.MaterialFadeThrough import com.google.android.material.transition.MaterialSharedAxis import org.oxycblt.auxio.R import org.oxycblt.auxio.databinding.FragmentSearchBinding @@ -70,10 +69,10 @@ class SearchFragment : override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - enterTransition = MaterialFadeThrough() - returnTransition = MaterialFadeThrough() - exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true) - reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false) + enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true) + returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false) + exitTransition = MaterialSharedAxis(MaterialSharedAxis.X, true) + reenterTransition = MaterialSharedAxis(MaterialSharedAxis.X, false) } override fun onCreateBinding(inflater: LayoutInflater) = FragmentSearchBinding.inflate(inflater) diff --git a/app/src/main/java/org/oxycblt/auxio/settings/Settings.kt b/app/src/main/java/org/oxycblt/auxio/settings/Settings.kt index 81ff48732..6b1658acf 100644 --- a/app/src/main/java/org/oxycblt/auxio/settings/Settings.kt +++ b/app/src/main/java/org/oxycblt/auxio/settings/Settings.kt @@ -63,11 +63,7 @@ class Settings(private val context: Context, private val callback: Callback? = n unlikelyToBeNull(callback).onSettingChanged(key) } - /** - * An interface for receiving some preference updates. Use/Extend this instead of - * [SharedPreferences.OnSharedPreferenceChangeListener] if possible, as it doesn't require a - * context. - */ + /** An interface for receiving some preference updates. */ interface Callback { fun onSettingChanged(key: String) } diff --git a/app/src/main/java/org/oxycblt/auxio/ui/recycler/AuxioRecyclerView.kt b/app/src/main/java/org/oxycblt/auxio/ui/recycler/AuxioRecyclerView.kt index acc103b5d..c97c30518 100644 --- a/app/src/main/java/org/oxycblt/auxio/ui/recycler/AuxioRecyclerView.kt +++ b/app/src/main/java/org/oxycblt/auxio/ui/recycler/AuxioRecyclerView.kt @@ -27,11 +27,7 @@ import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.RecyclerView import org.oxycblt.auxio.util.systemBarInsetsCompat -/** - * A [RecyclerView] that automatically applies insets to itself. - * - * TODO: Correctly handle edge-to-edge regarding scroll effects and saved scroll positions. - */ +/** A [RecyclerView] that enables some extra functionality for Auxio's use-case. */ open class AuxioRecyclerView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr: Int = 0) : @@ -58,12 +54,12 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr return insets } - fun setSpanSizeLookup(lookup: (Int) -> Boolean) { + inline fun setSpanSizeLookup(crossinline fullWidth: (Int) -> Boolean) { val glm = layoutManager as GridLayoutManager val spanCount = glm.spanCount glm.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() { - override fun getSpanSize(position: Int) = if (lookup(position)) spanCount else 1 + override fun getSpanSize(position: Int) = if (fullWidth(position)) spanCount else 1 } } } diff --git a/app/src/main/java/org/oxycblt/auxio/ui/recycler/DialogRecyclerView.kt b/app/src/main/java/org/oxycblt/auxio/ui/recycler/DialogRecyclerView.kt index fe452326a..77813e9cc 100644 --- a/app/src/main/java/org/oxycblt/auxio/ui/recycler/DialogRecyclerView.kt +++ b/app/src/main/java/org/oxycblt/auxio/ui/recycler/DialogRecyclerView.kt @@ -40,7 +40,6 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr RecyclerView(context, attrs, defStyleAttr) { private val topDivider = MaterialDivider(context) private val bottomDivider = MaterialDivider(context) - private val spacingMedium = context.getDimenSize(R.dimen.spacing_medium) init { diff --git a/app/src/main/res/layout/fragment_about.xml b/app/src/main/res/layout/fragment_about.xml index 24bf05b88..65ddcfd2c 100644 --- a/app/src/main/res/layout/fragment_about.xml +++ b/app/src/main/res/layout/fragment_about.xml @@ -6,6 +6,7 @@ android:layout_height="wrap_content" android:background="?attr/colorSurface" android:orientation="vertical" + android:transitionGroup="true" tools:context=".settings.AboutFragment"> diff --git a/app/src/main/res/values/styles_ui.xml b/app/src/main/res/values/styles_ui.xml index 7a35c98fb..5d4e3a1ea 100644 --- a/app/src/main/res/values/styles_ui.xml +++ b/app/src/main/res/values/styles_ui.xml @@ -145,7 +145,7 @@ 1 end ?android:attr/textColorSecondary - @style/TextAppearance.Auxio.LabelMedium + @style/TextAppearance.Auxio.BodySmall