android: Use autofit grid for games fragment
This commit is contained in:
parent
9cb7e7072d
commit
3878c6ced1
3 changed files with 72 additions and 28 deletions
|
@ -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.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.ViewTreeObserver.OnGlobalLayoutListener
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import androidx.core.view.WindowInsetsCompat
|
||||||
import androidx.core.view.updatePadding
|
import androidx.core.view.updatePadding
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
|
||||||
import com.google.android.material.color.MaterialColors
|
import com.google.android.material.color.MaterialColors
|
||||||
import org.yuzu.yuzu_emu.R
|
import org.yuzu.yuzu_emu.R
|
||||||
import org.yuzu.yuzu_emu.YuzuApplication
|
import org.yuzu.yuzu_emu.YuzuApplication
|
||||||
import org.yuzu.yuzu_emu.adapters.GameAdapter
|
import org.yuzu.yuzu_emu.adapters.GameAdapter
|
||||||
import org.yuzu.yuzu_emu.databinding.FragmentGridBinding
|
import org.yuzu.yuzu_emu.databinding.FragmentGridBinding
|
||||||
|
import org.yuzu.yuzu_emu.layout.AutofitGridLayoutManager
|
||||||
|
|
||||||
class PlatformGamesFragment : Fragment(), PlatformGamesView {
|
class PlatformGamesFragment : Fragment(), PlatformGamesView {
|
||||||
private val presenter = PlatformGamesPresenter(this)
|
private val presenter = PlatformGamesPresenter(this)
|
||||||
private var adapter: GameAdapter? = null
|
|
||||||
|
|
||||||
private var _binding: FragmentGridBinding? = null
|
private var _binding: FragmentGridBinding? = null
|
||||||
private val binding get() = _binding!!
|
private val binding get() = _binding!!
|
||||||
|
@ -39,27 +37,12 @@ class PlatformGamesFragment : Fragment(), PlatformGamesView {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
adapter = GameAdapter(requireActivity() as AppCompatActivity)
|
binding.gridGames.apply {
|
||||||
|
layoutManager = AutofitGridLayoutManager(
|
||||||
// Organize our grid layout based on the current view.
|
requireContext(),
|
||||||
if (isAdded) {
|
requireContext().resources.getDimensionPixelSize(R.dimen.card_width)
|
||||||
view.viewTreeObserver
|
)
|
||||||
.addOnGlobalLayoutListener(object : OnGlobalLayoutListener {
|
adapter = GameAdapter(requireActivity() as AppCompatActivity)
|
||||||
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
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add swipe down to refresh gesture
|
// Add swipe down to refresh gesture
|
||||||
|
@ -92,8 +75,8 @@ class PlatformGamesFragment : Fragment(), PlatformGamesView {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showGames(games: Cursor) {
|
override fun showGames(games: Cursor) {
|
||||||
if (adapter != null) {
|
if (binding.gridGames.adapter != null) {
|
||||||
adapter!!.swapCursor(games)
|
(binding.gridGames.adapter as GameAdapter).swapCursor(games)
|
||||||
}
|
}
|
||||||
updateTextView()
|
updateTextView()
|
||||||
}
|
}
|
||||||
|
@ -103,7 +86,7 @@ class PlatformGamesFragment : Fragment(), PlatformGamesView {
|
||||||
return
|
return
|
||||||
|
|
||||||
binding.gamelistEmptyText.visibility =
|
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() {
|
private fun setInsets() {
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<dimen name="spacing_list">64dp</dimen>
|
<dimen name="spacing_list">64dp</dimen>
|
||||||
<dimen name="spacing_fab">72dp</dimen>
|
<dimen name="spacing_fab">72dp</dimen>
|
||||||
<dimen name="menu_width">256dp</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="dialog_margin">20dp</dimen>
|
||||||
<dimen name="elevated_app_bar">3dp</dimen>
|
<dimen name="elevated_app_bar">3dp</dimen>
|
||||||
|
|
Loading…
Reference in a new issue