Compact Grid View Layout
All checks were successful
eden-license / license-header (pull_request) Successful in 33s
All checks were successful
eden-license / license-header (pull_request) Successful in 33s
This commit is contained in:
parent
41d88f7b5c
commit
a1125dc24c
6 changed files with 151 additions and 3 deletions
|
@ -36,17 +36,18 @@ import androidx.core.net.toUri
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import org.yuzu.yuzu_emu.NativeLibrary
|
import org.yuzu.yuzu_emu.NativeLibrary
|
||||||
|
import org.yuzu.yuzu_emu.databinding.CardGameGridCompactBinding
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
|
import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.Settings
|
import org.yuzu.yuzu_emu.features.settings.model.Settings
|
||||||
import org.yuzu.yuzu_emu.utils.NativeConfig
|
|
||||||
|
|
||||||
class GameAdapter(private val activity: AppCompatActivity) :
|
class GameAdapter(private val activity: AppCompatActivity) :
|
||||||
AbstractDiffAdapter<Game, GameAdapter.GameViewHolder>(exact = false) {
|
AbstractDiffAdapter<Game, GameAdapter.GameViewHolder>(exact = false) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val VIEW_TYPE_GRID = 0
|
const val VIEW_TYPE_GRID = 0
|
||||||
const val VIEW_TYPE_LIST = 1
|
const val VIEW_TYPE_GRID_COMPACT = 1
|
||||||
const val VIEW_TYPE_CAROUSEL = 2
|
const val VIEW_TYPE_LIST = 2
|
||||||
|
const val VIEW_TYPE_CAROUSEL = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
private var viewType = 0
|
private var viewType = 0
|
||||||
|
@ -80,6 +81,7 @@ class GameAdapter(private val activity: AppCompatActivity) :
|
||||||
listBinding.root.layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT
|
listBinding.root.layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
listBinding.root.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT
|
listBinding.root.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT
|
||||||
}
|
}
|
||||||
|
|
||||||
VIEW_TYPE_GRID -> {
|
VIEW_TYPE_GRID -> {
|
||||||
val gridBinding = holder.binding as CardGameGridBinding
|
val gridBinding = holder.binding as CardGameGridBinding
|
||||||
gridBinding.cardGameGrid.scaleX = 1f
|
gridBinding.cardGameGrid.scaleX = 1f
|
||||||
|
@ -89,6 +91,17 @@ class GameAdapter(private val activity: AppCompatActivity) :
|
||||||
gridBinding.root.layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT
|
gridBinding.root.layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
gridBinding.root.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT
|
gridBinding.root.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VIEW_TYPE_GRID_COMPACT -> {
|
||||||
|
val gridCompactBinding = holder.binding as CardGameGridCompactBinding
|
||||||
|
gridCompactBinding.cardGameGridCompact.scaleX = 1f
|
||||||
|
gridCompactBinding.cardGameGridCompact.scaleY = 1f
|
||||||
|
gridCompactBinding.cardGameGridCompact.alpha = 1f
|
||||||
|
// Reset layout params to XML defaults (same as normal grid)
|
||||||
|
gridCompactBinding.root.layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
|
gridCompactBinding.root.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT
|
||||||
|
}
|
||||||
|
|
||||||
VIEW_TYPE_CAROUSEL -> {
|
VIEW_TYPE_CAROUSEL -> {
|
||||||
val carouselBinding = holder.binding as CardGameCarouselBinding
|
val carouselBinding = holder.binding as CardGameCarouselBinding
|
||||||
// soothens transient flickering
|
// soothens transient flickering
|
||||||
|
@ -105,16 +118,25 @@ class GameAdapter(private val activity: AppCompatActivity) :
|
||||||
parent,
|
parent,
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
|
|
||||||
VIEW_TYPE_GRID -> CardGameGridBinding.inflate(
|
VIEW_TYPE_GRID -> CardGameGridBinding.inflate(
|
||||||
LayoutInflater.from(parent.context),
|
LayoutInflater.from(parent.context),
|
||||||
parent,
|
parent,
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
|
|
||||||
|
VIEW_TYPE_GRID_COMPACT -> CardGameGridCompactBinding.inflate(
|
||||||
|
LayoutInflater.from(parent.context),
|
||||||
|
parent,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
VIEW_TYPE_CAROUSEL -> CardGameCarouselBinding.inflate(
|
VIEW_TYPE_CAROUSEL -> CardGameCarouselBinding.inflate(
|
||||||
LayoutInflater.from(parent.context),
|
LayoutInflater.from(parent.context),
|
||||||
parent,
|
parent,
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
|
|
||||||
else -> throw IllegalArgumentException("Invalid view type")
|
else -> throw IllegalArgumentException("Invalid view type")
|
||||||
}
|
}
|
||||||
return GameViewHolder(binding, viewType)
|
return GameViewHolder(binding, viewType)
|
||||||
|
@ -130,6 +152,7 @@ class GameAdapter(private val activity: AppCompatActivity) :
|
||||||
VIEW_TYPE_LIST -> bindListView(model)
|
VIEW_TYPE_LIST -> bindListView(model)
|
||||||
VIEW_TYPE_GRID -> bindGridView(model)
|
VIEW_TYPE_GRID -> bindGridView(model)
|
||||||
VIEW_TYPE_CAROUSEL -> bindCarouselView(model)
|
VIEW_TYPE_CAROUSEL -> bindCarouselView(model)
|
||||||
|
VIEW_TYPE_GRID_COMPACT -> bindGridCompactView(model)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,6 +191,23 @@ class GameAdapter(private val activity: AppCompatActivity) :
|
||||||
gridBinding.root.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT
|
gridBinding.root.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun bindGridCompactView(model: Game) {
|
||||||
|
val gridCompactBinding = binding as CardGameGridCompactBinding
|
||||||
|
|
||||||
|
gridCompactBinding.imageGameScreenCompact.scaleType = ImageView.ScaleType.CENTER_CROP
|
||||||
|
GameIconUtils.loadGameIcon(model, gridCompactBinding.imageGameScreenCompact)
|
||||||
|
|
||||||
|
gridCompactBinding.textGameTitleCompact.text = model.title.replace("[\\t\\n\\r]+".toRegex(), " ")
|
||||||
|
|
||||||
|
gridCompactBinding.textGameTitleCompact.marquee()
|
||||||
|
gridCompactBinding.cardGameGridCompact.setOnClickListener { onClick(model) }
|
||||||
|
gridCompactBinding.cardGameGridCompact.setOnLongClickListener { onLongClick(model) }
|
||||||
|
|
||||||
|
// Reset layout params to XML defaults (same as normal grid)
|
||||||
|
gridCompactBinding.root.layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
|
gridCompactBinding.root.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT
|
||||||
|
}
|
||||||
|
|
||||||
private fun bindCarouselView(model: Game) {
|
private fun bindCarouselView(model: Game) {
|
||||||
val carouselBinding = binding as CardGameCarouselBinding
|
val carouselBinding = binding as CardGameCarouselBinding
|
||||||
|
|
||||||
|
|
|
@ -194,6 +194,10 @@ class GamesFragment : Fragment() {
|
||||||
val columns = resources.getInteger(R.integer.game_columns_grid)
|
val columns = resources.getInteger(R.integer.game_columns_grid)
|
||||||
GridLayoutManager(context, columns)
|
GridLayoutManager(context, columns)
|
||||||
}
|
}
|
||||||
|
GameAdapter.VIEW_TYPE_GRID_COMPACT -> {
|
||||||
|
val columns = resources.getInteger(R.integer.game_columns_grid)
|
||||||
|
GridLayoutManager(context, columns)
|
||||||
|
}
|
||||||
GameAdapter.VIEW_TYPE_LIST -> {
|
GameAdapter.VIEW_TYPE_LIST -> {
|
||||||
val columns = resources.getInteger(R.integer.game_columns_list)
|
val columns = resources.getInteger(R.integer.game_columns_list)
|
||||||
GridLayoutManager(context, columns)
|
GridLayoutManager(context, columns)
|
||||||
|
@ -300,6 +304,7 @@ class GamesFragment : Fragment() {
|
||||||
val currentViewType = getCurrentViewType()
|
val currentViewType = getCurrentViewType()
|
||||||
when (currentViewType) {
|
when (currentViewType) {
|
||||||
GameAdapter.VIEW_TYPE_LIST -> popup.menu.findItem(R.id.view_list).isChecked = true
|
GameAdapter.VIEW_TYPE_LIST -> popup.menu.findItem(R.id.view_list).isChecked = true
|
||||||
|
GameAdapter.VIEW_TYPE_GRID_COMPACT -> popup.menu.findItem(R.id.view_grid_compact).isChecked = true
|
||||||
GameAdapter.VIEW_TYPE_GRID -> popup.menu.findItem(R.id.view_grid).isChecked = true
|
GameAdapter.VIEW_TYPE_GRID -> popup.menu.findItem(R.id.view_grid).isChecked = true
|
||||||
GameAdapter.VIEW_TYPE_CAROUSEL -> popup.menu.findItem(R.id.view_carousel).isChecked = true
|
GameAdapter.VIEW_TYPE_CAROUSEL -> popup.menu.findItem(R.id.view_carousel).isChecked = true
|
||||||
}
|
}
|
||||||
|
@ -314,6 +319,14 @@ class GamesFragment : Fragment() {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
R.id.view_grid_compact -> {
|
||||||
|
if (getCurrentViewType() == GameAdapter.VIEW_TYPE_CAROUSEL) onPause()
|
||||||
|
setCurrentViewType(GameAdapter.VIEW_TYPE_GRID_COMPACT)
|
||||||
|
applyGridGamesBinding()
|
||||||
|
item.isChecked = true
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
R.id.view_list -> {
|
R.id.view_list -> {
|
||||||
if (getCurrentViewType() == GameAdapter.VIEW_TYPE_CAROUSEL) onPause()
|
if (getCurrentViewType() == GameAdapter.VIEW_TYPE_CAROUSEL) onPause()
|
||||||
setCurrentViewType(GameAdapter.VIEW_TYPE_LIST)
|
setCurrentViewType(GameAdapter.VIEW_TYPE_LIST)
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<gradient
|
||||||
|
android:angle="270"
|
||||||
|
android:startColor="@android:color/transparent"
|
||||||
|
android:centerColor="#66000000"
|
||||||
|
android:endColor="#AA000000"
|
||||||
|
android:type="linear" />
|
||||||
|
</shape>
|
|
@ -0,0 +1,82 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:focusable="false"
|
||||||
|
android:focusableInTouchMode="false"
|
||||||
|
android:padding="4dp">
|
||||||
|
|
||||||
|
<org.yuzu.yuzu_emu.views.GradientBorderCardView
|
||||||
|
android:id="@+id/card_game_grid_compact"
|
||||||
|
app:cardElevation="0dp"
|
||||||
|
app:cardBackgroundColor="@color/eden_card_background"
|
||||||
|
app:strokeWidth="0dp"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_margin="4dp"
|
||||||
|
android:clickable="true"
|
||||||
|
android:clipToPadding="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:transitionName="card_game_compact"
|
||||||
|
app:cardCornerRadius="16dp"
|
||||||
|
android:foreground="@color/eden_border_gradient_start">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingTop="14dp"
|
||||||
|
android:paddingLeft="6dp"
|
||||||
|
android:paddingRight="6dp"
|
||||||
|
android:paddingBottom="6dp">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/image_container"
|
||||||
|
android:layout_width="150dp"
|
||||||
|
android:layout_height="100dp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<com.google.android.material.imageview.ShapeableImageView
|
||||||
|
android:id="@+id/image_game_screen_compact"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:shapeAppearance="@style/ShapeAppearance.Material3.Corner.Medium"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
tools:src="@drawable/default_icon" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@drawable/gradient_overlay_bottom" />
|
||||||
|
|
||||||
|
<com.google.android.material.textview.MaterialTextView
|
||||||
|
android:id="@+id/text_game_title_compact"
|
||||||
|
style="@style/SynthwaveText.Body"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:layout_margin="6dp"
|
||||||
|
android:requiresFadingEdge="horizontal"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@android:color/white"
|
||||||
|
android:shadowColor="@android:color/black"
|
||||||
|
android:shadowDx="1"
|
||||||
|
android:shadowDy="1"
|
||||||
|
android:shadowRadius="2"
|
||||||
|
android:maxLines="2"
|
||||||
|
android:ellipsize="end"
|
||||||
|
tools:text="The Legend of Zelda: Skyward Sword" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
</org.yuzu.yuzu_emu.views.GradientBorderCardView>
|
||||||
|
|
||||||
|
</FrameLayout>
|
|
@ -4,6 +4,9 @@
|
||||||
<item
|
<item
|
||||||
android:id="@+id/view_grid"
|
android:id="@+id/view_grid"
|
||||||
android:title="@string/view_grid"/>
|
android:title="@string/view_grid"/>
|
||||||
|
<item
|
||||||
|
android:id="@+id/view_grid_compact"
|
||||||
|
android:title="@string/view_grid_compact"/>
|
||||||
<item
|
<item
|
||||||
android:id="@+id/view_list"
|
android:id="@+id/view_list"
|
||||||
android:title="@string/view_list"
|
android:title="@string/view_list"
|
||||||
|
|
|
@ -266,6 +266,7 @@
|
||||||
<string name="alphabetical">Alphabetical</string>
|
<string name="alphabetical">Alphabetical</string>
|
||||||
<string name="view_list">List</string>
|
<string name="view_list">List</string>
|
||||||
<string name="view_grid">Grid</string>
|
<string name="view_grid">Grid</string>
|
||||||
|
<string name="view_grid_compact">Compact Grid</string>
|
||||||
<string name="view_carousel">Carousel</string>
|
<string name="view_carousel">Carousel</string>
|
||||||
<string name="game_image_desc">Screenshot for %1$s</string>
|
<string name="game_image_desc">Screenshot for %1$s</string>
|
||||||
<string name="folder">Folder</string>
|
<string name="folder">Folder</string>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue