android: Use autofit grid for games fragment
This commit is contained in:
		| @@ -0,0 +1,61 @@ | ||||
| // SPDX-FileCopyrightText: 2023 yuzu Emulator Project | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| package org.yuzu.yuzu_emu.layout | ||||
|  | ||||
| import android.content.Context | ||||
| import androidx.recyclerview.widget.GridLayoutManager | ||||
| import androidx.recyclerview.widget.RecyclerView | ||||
| import androidx.recyclerview.widget.RecyclerView.Recycler | ||||
| import org.yuzu.yuzu_emu.R | ||||
|  | ||||
| /** | ||||
|  *  Cut down version of the solution provided here | ||||
|  *  https://stackoverflow.com/questions/26666143/recyclerview-gridlayoutmanager-how-to-auto-detect-span-count | ||||
|  */ | ||||
| class AutofitGridLayoutManager( | ||||
|     context: Context, | ||||
|     columnWidth: Int | ||||
| ) : GridLayoutManager(context, 1) { | ||||
|     private var columnWidth = 0 | ||||
|     private var isColumnWidthChanged = true | ||||
|     private var lastWidth = 0 | ||||
|     private var lastHeight = 0 | ||||
|  | ||||
|     init { | ||||
|         setColumnWidth(checkedColumnWidth(context, columnWidth)) | ||||
|     } | ||||
|  | ||||
|     private fun checkedColumnWidth(context: Context, columnWidth: Int): Int { | ||||
|         var newColumnWidth = columnWidth | ||||
|         if (newColumnWidth <= 0) { | ||||
|             newColumnWidth = context.resources.getDimensionPixelSize(R.dimen.spacing_xtralarge) | ||||
|         } | ||||
|         return newColumnWidth | ||||
|     } | ||||
|  | ||||
|     private fun setColumnWidth(newColumnWidth: Int) { | ||||
|         if (newColumnWidth > 0 && newColumnWidth != columnWidth) { | ||||
|             columnWidth = newColumnWidth | ||||
|             isColumnWidthChanged = true | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     override fun onLayoutChildren(recycler: Recycler, state: RecyclerView.State) { | ||||
|         val width = width | ||||
|         val height = height | ||||
|         if (columnWidth > 0 && width > 0 && height > 0 && (isColumnWidthChanged || lastWidth != width || lastHeight != height)) { | ||||
|             val totalSpace: Int = if (orientation == VERTICAL) { | ||||
|                 width - paddingRight - paddingLeft | ||||
|             } else { | ||||
|                 height - paddingTop - paddingBottom | ||||
|             } | ||||
|             val spanCount = 1.coerceAtLeast(totalSpace / columnWidth) | ||||
|             setSpanCount(spanCount) | ||||
|             isColumnWidthChanged = false | ||||
|         } | ||||
|         lastWidth = width | ||||
|         lastHeight = height | ||||
|         super.onLayoutChildren(recycler, state) | ||||
|     } | ||||
| } | ||||
| @@ -8,22 +8,20 @@ import android.os.Bundle | ||||
| import android.view.LayoutInflater | ||||
| import android.view.View | ||||
| import android.view.ViewGroup | ||||
| import android.view.ViewTreeObserver.OnGlobalLayoutListener | ||||
| import androidx.appcompat.app.AppCompatActivity | ||||
| import androidx.core.view.ViewCompat | ||||
| import androidx.core.view.WindowInsetsCompat | ||||
| import androidx.core.view.updatePadding | ||||
| import androidx.fragment.app.Fragment | ||||
| import androidx.recyclerview.widget.GridLayoutManager | ||||
| import com.google.android.material.color.MaterialColors | ||||
| import org.yuzu.yuzu_emu.R | ||||
| import org.yuzu.yuzu_emu.YuzuApplication | ||||
| import org.yuzu.yuzu_emu.adapters.GameAdapter | ||||
| import org.yuzu.yuzu_emu.databinding.FragmentGridBinding | ||||
| import org.yuzu.yuzu_emu.layout.AutofitGridLayoutManager | ||||
|  | ||||
| class PlatformGamesFragment : Fragment(), PlatformGamesView { | ||||
|     private val presenter = PlatformGamesPresenter(this) | ||||
|     private var adapter: GameAdapter? = null | ||||
|  | ||||
|     private var _binding: FragmentGridBinding? = null | ||||
|     private val binding get() = _binding!! | ||||
| @@ -39,27 +37,12 @@ class PlatformGamesFragment : Fragment(), PlatformGamesView { | ||||
|     } | ||||
|  | ||||
|     override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | ||||
|         adapter = GameAdapter(requireActivity() as AppCompatActivity) | ||||
|  | ||||
|         // Organize our grid layout based on the current view. | ||||
|         if (isAdded) { | ||||
|             view.viewTreeObserver | ||||
|                 .addOnGlobalLayoutListener(object : OnGlobalLayoutListener { | ||||
|                     override fun onGlobalLayout() { | ||||
|                         if (view.measuredWidth == 0) { | ||||
|                             return | ||||
|                         } | ||||
|                         var columns = view.measuredWidth / | ||||
|                                 requireContext().resources.getDimensionPixelSize(R.dimen.card_width) | ||||
|                         if (columns == 0) { | ||||
|                             columns = 1 | ||||
|                         } | ||||
|                         view.viewTreeObserver.removeOnGlobalLayoutListener(this) | ||||
|                         val layoutManager = GridLayoutManager(activity, columns) | ||||
|                         binding.gridGames.layoutManager = layoutManager | ||||
|                         binding.gridGames.adapter = adapter | ||||
|                     } | ||||
|                 }) | ||||
|         binding.gridGames.apply { | ||||
|             layoutManager = AutofitGridLayoutManager( | ||||
|                 requireContext(), | ||||
|                 requireContext().resources.getDimensionPixelSize(R.dimen.card_width) | ||||
|             ) | ||||
|             adapter = GameAdapter(requireActivity() as AppCompatActivity) | ||||
|         } | ||||
|  | ||||
|         // Add swipe down to refresh gesture | ||||
| @@ -92,8 +75,8 @@ class PlatformGamesFragment : Fragment(), PlatformGamesView { | ||||
|     } | ||||
|  | ||||
|     override fun showGames(games: Cursor) { | ||||
|         if (adapter != null) { | ||||
|             adapter!!.swapCursor(games) | ||||
|         if (binding.gridGames.adapter != null) { | ||||
|             (binding.gridGames.adapter as GameAdapter).swapCursor(games) | ||||
|         } | ||||
|         updateTextView() | ||||
|     } | ||||
| @@ -103,7 +86,7 @@ class PlatformGamesFragment : Fragment(), PlatformGamesView { | ||||
|             return | ||||
|  | ||||
|         binding.gamelistEmptyText.visibility = | ||||
|             if (adapter!!.itemCount == 0) View.VISIBLE else View.GONE | ||||
|             if ((binding.gridGames.adapter as GameAdapter).itemCount == 0) View.VISIBLE else View.GONE | ||||
|     } | ||||
|  | ||||
|     private fun setInsets() { | ||||
|   | ||||
| @@ -6,7 +6,7 @@ | ||||
|     <dimen name="spacing_list">64dp</dimen> | ||||
|     <dimen name="spacing_fab">72dp</dimen> | ||||
|     <dimen name="menu_width">256dp</dimen> | ||||
|     <dimen name="card_width">150dp</dimen> | ||||
|     <dimen name="card_width">170dp</dimen> | ||||
|  | ||||
|     <dimen name="dialog_margin">20dp</dimen> | ||||
|     <dimen name="elevated_app_bar">3dp</dimen> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user