summaryrefslogtreecommitdiff
path: root/src/android
diff options
context:
space:
mode:
authorGravatar Charles Lombardo2023-03-23 13:26:05 -0400
committerGravatar bunnei2023-06-03 00:05:47 -0700
commit3878c6ced1e25265e1a84f85f23cebbd62ce98b8 (patch)
treed73f9e796880e0252cc47e24e656d34c4269d6f4 /src/android
parentandroid: Prevent updating empty game list text on invalid view (diff)
downloadyuzu-3878c6ced1e25265e1a84f85f23cebbd62ce98b8.tar.gz
yuzu-3878c6ced1e25265e1a84f85f23cebbd62ce98b8.tar.xz
yuzu-3878c6ced1e25265e1a84f85f23cebbd62ce98b8.zip
android: Use autofit grid for games fragment
Diffstat (limited to 'src/android')
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/layout/AutofitGridLayoutManager.kt61
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/platform/PlatformGamesFragment.kt37
-rw-r--r--src/android/app/src/main/res/values/dimens.xml2
3 files changed, 72 insertions, 28 deletions
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/layout/AutofitGridLayoutManager.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/layout/AutofitGridLayoutManager.kt
new file mode 100644
index 000000000..be5e4c86c
--- /dev/null
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/layout/AutofitGridLayoutManager.kt
@@ -0,0 +1,61 @@
1// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4package org.yuzu.yuzu_emu.layout
5
6import android.content.Context
7import androidx.recyclerview.widget.GridLayoutManager
8import androidx.recyclerview.widget.RecyclerView
9import androidx.recyclerview.widget.RecyclerView.Recycler
10import org.yuzu.yuzu_emu.R
11
12/**
13 * Cut down version of the solution provided here
14 * https://stackoverflow.com/questions/26666143/recyclerview-gridlayoutmanager-how-to-auto-detect-span-count
15 */
16class AutofitGridLayoutManager(
17 context: Context,
18 columnWidth: Int
19) : GridLayoutManager(context, 1) {
20 private var columnWidth = 0
21 private var isColumnWidthChanged = true
22 private var lastWidth = 0
23 private var lastHeight = 0
24
25 init {
26 setColumnWidth(checkedColumnWidth(context, columnWidth))
27 }
28
29 private fun checkedColumnWidth(context: Context, columnWidth: Int): Int {
30 var newColumnWidth = columnWidth
31 if (newColumnWidth <= 0) {
32 newColumnWidth = context.resources.getDimensionPixelSize(R.dimen.spacing_xtralarge)
33 }
34 return newColumnWidth
35 }
36
37 private fun setColumnWidth(newColumnWidth: Int) {
38 if (newColumnWidth > 0 && newColumnWidth != columnWidth) {
39 columnWidth = newColumnWidth
40 isColumnWidthChanged = true
41 }
42 }
43
44 override fun onLayoutChildren(recycler: Recycler, state: RecyclerView.State) {
45 val width = width
46 val height = height
47 if (columnWidth > 0 && width > 0 && height > 0 && (isColumnWidthChanged || lastWidth != width || lastHeight != height)) {
48 val totalSpace: Int = if (orientation == VERTICAL) {
49 width - paddingRight - paddingLeft
50 } else {
51 height - paddingTop - paddingBottom
52 }
53 val spanCount = 1.coerceAtLeast(totalSpace / columnWidth)
54 setSpanCount(spanCount)
55 isColumnWidthChanged = false
56 }
57 lastWidth = width
58 lastHeight = height
59 super.onLayoutChildren(recycler, state)
60 }
61}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/platform/PlatformGamesFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/platform/PlatformGamesFragment.kt
index 7b8d7c5a3..998a00847 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/platform/PlatformGamesFragment.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/platform/PlatformGamesFragment.kt
@@ -8,22 +8,20 @@ import android.os.Bundle
8import android.view.LayoutInflater 8import android.view.LayoutInflater
9import android.view.View 9import android.view.View
10import android.view.ViewGroup 10import android.view.ViewGroup
11import android.view.ViewTreeObserver.OnGlobalLayoutListener
12import androidx.appcompat.app.AppCompatActivity 11import androidx.appcompat.app.AppCompatActivity
13import androidx.core.view.ViewCompat 12import androidx.core.view.ViewCompat
14import androidx.core.view.WindowInsetsCompat 13import androidx.core.view.WindowInsetsCompat
15import androidx.core.view.updatePadding 14import androidx.core.view.updatePadding
16import androidx.fragment.app.Fragment 15import androidx.fragment.app.Fragment
17import androidx.recyclerview.widget.GridLayoutManager
18import com.google.android.material.color.MaterialColors 16import com.google.android.material.color.MaterialColors
19import org.yuzu.yuzu_emu.R 17import org.yuzu.yuzu_emu.R
20import org.yuzu.yuzu_emu.YuzuApplication 18import org.yuzu.yuzu_emu.YuzuApplication
21import org.yuzu.yuzu_emu.adapters.GameAdapter 19import org.yuzu.yuzu_emu.adapters.GameAdapter
22import org.yuzu.yuzu_emu.databinding.FragmentGridBinding 20import org.yuzu.yuzu_emu.databinding.FragmentGridBinding
21import org.yuzu.yuzu_emu.layout.AutofitGridLayoutManager
23 22
24class PlatformGamesFragment : Fragment(), PlatformGamesView { 23class PlatformGamesFragment : Fragment(), PlatformGamesView {
25 private val presenter = PlatformGamesPresenter(this) 24 private val presenter = PlatformGamesPresenter(this)
26 private var adapter: GameAdapter? = null
27 25
28 private var _binding: FragmentGridBinding? = null 26 private var _binding: FragmentGridBinding? = null
29 private val binding get() = _binding!! 27 private val binding get() = _binding!!
@@ -39,27 +37,12 @@ class PlatformGamesFragment : Fragment(), PlatformGamesView {
39 } 37 }
40 38
41 override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 39 override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
42 adapter = GameAdapter(requireActivity() as AppCompatActivity) 40 binding.gridGames.apply {
43 41 layoutManager = AutofitGridLayoutManager(
44 // Organize our grid layout based on the current view. 42 requireContext(),
45 if (isAdded) { 43 requireContext().resources.getDimensionPixelSize(R.dimen.card_width)
46 view.viewTreeObserver 44 )
47 .addOnGlobalLayoutListener(object : OnGlobalLayoutListener { 45 adapter = GameAdapter(requireActivity() as AppCompatActivity)
48 override fun onGlobalLayout() {
49 if (view.measuredWidth == 0) {
50 return
51 }
52 var columns = view.measuredWidth /
53 requireContext().resources.getDimensionPixelSize(R.dimen.card_width)
54 if (columns == 0) {
55 columns = 1
56 }
57 view.viewTreeObserver.removeOnGlobalLayoutListener(this)
58 val layoutManager = GridLayoutManager(activity, columns)
59 binding.gridGames.layoutManager = layoutManager
60 binding.gridGames.adapter = adapter
61 }
62 })
63 } 46 }
64 47
65 // Add swipe down to refresh gesture 48 // Add swipe down to refresh gesture
@@ -92,8 +75,8 @@ class PlatformGamesFragment : Fragment(), PlatformGamesView {
92 } 75 }
93 76
94 override fun showGames(games: Cursor) { 77 override fun showGames(games: Cursor) {
95 if (adapter != null) { 78 if (binding.gridGames.adapter != null) {
96 adapter!!.swapCursor(games) 79 (binding.gridGames.adapter as GameAdapter).swapCursor(games)
97 } 80 }
98 updateTextView() 81 updateTextView()
99 } 82 }
@@ -103,7 +86,7 @@ class PlatformGamesFragment : Fragment(), PlatformGamesView {
103 return 86 return
104 87
105 binding.gamelistEmptyText.visibility = 88 binding.gamelistEmptyText.visibility =
106 if (adapter!!.itemCount == 0) View.VISIBLE else View.GONE 89 if ((binding.gridGames.adapter as GameAdapter).itemCount == 0) View.VISIBLE else View.GONE
107 } 90 }
108 91
109 private fun setInsets() { 92 private fun setInsets() {
diff --git a/src/android/app/src/main/res/values/dimens.xml b/src/android/app/src/main/res/values/dimens.xml
index 0b028a167..5573d6922 100644
--- a/src/android/app/src/main/res/values/dimens.xml
+++ b/src/android/app/src/main/res/values/dimens.xml
@@ -6,7 +6,7 @@
6 <dimen name="spacing_list">64dp</dimen> 6 <dimen name="spacing_list">64dp</dimen>
7 <dimen name="spacing_fab">72dp</dimen> 7 <dimen name="spacing_fab">72dp</dimen>
8 <dimen name="menu_width">256dp</dimen> 8 <dimen name="menu_width">256dp</dimen>
9 <dimen name="card_width">150dp</dimen> 9 <dimen name="card_width">170dp</dimen>
10 10
11 <dimen name="dialog_margin">20dp</dimen> 11 <dimen name="dialog_margin">20dp</dimen>
12 <dimen name="elevated_app_bar">3dp</dimen> 12 <dimen name="elevated_app_bar">3dp</dimen>