Browse Source

+async cardsize & bottominset

pull/3028/head
Allison Cunha 3 months ago
committed by crueter
parent
commit
85244fcd53
  1. 19
      src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/GamesFragment.kt
  2. 86
      src/android/app/src/main/java/org/yuzu/yuzu_emu/views/CarouselRecyclerView.kt

19
src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/GamesFragment.kt

@ -53,6 +53,7 @@ class GamesFragment : Fragment() {
private var originalHeaderLeftMargin: Int? = null
private var lastViewType: Int = GameAdapter.VIEW_TYPE_GRID
private var fallbackBottomInset: Int = 0
companion object {
private const val SEARCH_TEXT = "SearchText"
@ -208,12 +209,12 @@ class GamesFragment : Fragment() {
else -> throw IllegalArgumentException("Invalid view type: $savedViewType")
}
if (savedViewType == GameAdapter.VIEW_TYPE_CAROUSEL) {
doOnNextLayout {
(this as? CarouselRecyclerView)?.setCarouselMode(true, gameAdapter)
adapter = gameAdapter
(binding.gridGames as? View)?.let { it -> ViewCompat.requestApplyInsets(it)}
doOnNextLayout { //Carousel: important to avoid overlap issues
(this as? CarouselRecyclerView)?.notifyLaidOut(fallbackBottomInset)
}
} else {
(this as? CarouselRecyclerView)?.setCarouselMode(false)
(this as? CarouselRecyclerView)?.setupCarousel(false)
}
adapter = gameAdapter
lastViewType = savedViewType
@ -237,9 +238,8 @@ class GamesFragment : Fragment() {
override fun onResume() {
super.onResume()
if (getCurrentViewType() == GameAdapter.VIEW_TYPE_CAROUSEL) {
(binding.gridGames as? CarouselRecyclerView)?.restoreScrollState(
gamesViewModel.lastScrollPosition
)
(binding.gridGames as? CarouselRecyclerView)?.setupCarousel(true)
(binding.gridGames as? CarouselRecyclerView)?.restoreScrollState(gamesViewModel.lastScrollPosition)
}
}
@ -494,6 +494,11 @@ class GamesFragment : Fragment() {
mlpFab.rightMargin = rightInset + fabPadding
binding.addDirectory.layoutParams = mlpFab
val navInsets = windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars())
val gestureInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemGestures())
val bottomInset = maxOf(navInsets.bottom, gestureInsets.bottom, cutoutInsets.bottom)
fallbackBottomInset = bottomInset
(binding.gridGames as? CarouselRecyclerView)?.notifyInsetsReady(bottomInset)
windowInsets
}
}

86
src/android/app/src/main/java/org/yuzu/yuzu_emu/views/CarouselRecyclerView.kt

@ -20,9 +20,8 @@ import androidx.core.view.doOnNextLayout
import org.yuzu.yuzu_emu.YuzuApplication
import androidx.preference.PreferenceManager
import androidx.core.view.WindowInsetsCompat
/**
* CarouselRecyclerView encapsulates all carousel logic for the games UI.
* CarouselRecyclerView encapsulates all carousel content for the games UI.
* It manages overlapping cards, center snapping, custom drawing order,
* joypad & fling navigation and mid-screen swipe-to-refresh.
*/
@ -34,6 +33,7 @@ class CarouselRecyclerView @JvmOverloads constructor(
private var overlapFactor: Float = 0f
private var overlapPx: Int = 0
private var bottomInset: Int = -1
private var overlapDecoration: OverlappingDecoration? = null
private var pagerSnapHelper: PagerSnapHelper? = null
private var scalingScrollListener: OnScrollListener? = null
@ -202,46 +202,61 @@ class CarouselRecyclerView @JvmOverloads constructor(
}
}
fun setCarouselMode(enabled: Boolean, gameAdapter: GameAdapter? = null) {
fun refreshView() {
updateChildScalesAndAlpha()
focusCenteredCard()
}
fun notifyInsetsReady(newBottomInset: Int) {
if (bottomInset != newBottomInset) {
bottomInset = newBottomInset
}
setupCarousel(true)
}
fun notifyLaidOut(fallBackBottomInset: Int) {
if (bottomInset < 0) bottomInset = fallBackBottomInset
var gameAdapter = adapter as? GameAdapter ?: return
var newCardSize = cardSize(bottomInset)
if (gameAdapter.cardSize != newCardSize) {
gameAdapter.setCardSize(newCardSize)
}
setupCarousel(true)
}
fun cardSize(bottomInset: Int): Int {
val internalFactor = resources.getFraction(R.fraction.carousel_card_size_factor, 1, 1)
val userFactor = preferences.getFloat(CAROUSEL_CARD_SIZE_FACTOR, internalFactor).coerceIn(
0f,
1f
)
return (userFactor * (height - bottomInset)).toInt()
}
fun setupCarousel(enabled: Boolean) {
if (enabled) {
useCustomDrawingOrder = true
val gameAdapter = adapter as? GameAdapter ?: return
if (gameAdapter.cardSize == 0) return
if (bottomInset < 0) return
val insets = rootWindowInsets?.let { WindowInsetsCompat.toWindowInsetsCompat(it, this) }
val bottomInset = insets?.getInsets(WindowInsetsCompat.Type.systemBars())?.bottom ?: 0
val internalFactor = resources.getFraction(R.fraction.carousel_card_size_factor, 1, 1)
val userFactor = preferences.getFloat(CAROUSEL_CARD_SIZE_FACTOR, internalFactor).coerceIn(
0f,
1f
)
val cardSize = (userFactor * (height - bottomInset)).toInt()
gameAdapter?.setCardSize(cardSize)
useCustomDrawingOrder = true
val cardSize = gameAdapter.cardSize
val internalOverlapFactor = resources.getFraction(
R.fraction.carousel_overlap_factor,
1,
1
)
overlapFactor = preferences.getFloat(CAROUSEL_OVERLAP_FACTOR, internalOverlapFactor).coerceIn(
0f,
1f
)
val internalOverlapFactor = resources.getFraction(R.fraction.carousel_overlap_factor,1,1)
overlapFactor = preferences.getFloat(CAROUSEL_OVERLAP_FACTOR, internalOverlapFactor).coerceIn(0f,1f)
overlapPx = (cardSize * overlapFactor).toInt()
val internalFlingMultiplier = resources.getFraction(
R.fraction.carousel_fling_multiplier,
1,
1
)
val internalFlingMultiplier = resources.getFraction(R.fraction.carousel_fling_multiplier,1,1)
flingMultiplier = preferences.getFloat(
CAROUSEL_FLING_MULTIPLIER,
internalFlingMultiplier
).coerceIn(1f, 5f)
gameAdapter?.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
gameAdapter .registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
override fun onChanged() {
if (pendingScrollAfterReload) {
post {
jigglyScroll()
doOnNextLayout {
refreshView()
pendingScrollAfterReload = false
}
}
@ -257,7 +272,7 @@ class CarouselRecyclerView @JvmOverloads constructor(
addItemDecoration(overlapDecoration!!)
}
// Gradual scalingAdd commentMore actions
// Gradual scaling on scroll
if (scalingScrollListener == null) {
scalingScrollListener = object : OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
@ -315,8 +330,7 @@ class CarouselRecyclerView @JvmOverloads constructor(
super.scrollToPosition(position)
(layoutManager as? LinearLayoutManager)?.scrollToPositionWithOffset(position, overlapPx)
doOnNextLayout {
updateChildScalesAndAlpha()
focusCenteredCard()
refreshView()
}
}
@ -382,12 +396,6 @@ class CarouselRecyclerView @JvmOverloads constructor(
return sorted[i].first
}
fun jigglyScroll() {
scrollBy(-1, 0)
scrollBy(1, 0)
focusCenteredCard()
}
inner class OverlappingDecoration(private val overlap: Int) : ItemDecoration() {
override fun getItemOffsets(
outRect: Rect,

Loading…
Cancel
Save