[android / GameUI] Add grid compact layout and fix ugly borders on grid layout (#401)
Tis PR adds a new layout for the Game Adapter with shorter cards and fixes the ugly borders in Game Adapter's Grid layout. Reviewed-on: #401 Reviewed-by: crueter <crueter@eden-emu.dev> Reviewed-by: MaranBr <maranbr@eden-emu.dev> Co-authored-by: Nixyn <contact@innix.space> Co-committed-by: Nixyn <contact@innix.space>
This commit is contained in:
parent
2990f30a70
commit
ab6ffeef58
7 changed files with 161 additions and 8 deletions
|
@ -36,17 +36,18 @@ import androidx.core.net.toUri
|
|||
import androidx.core.content.edit
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
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.Settings
|
||||
import org.yuzu.yuzu_emu.utils.NativeConfig
|
||||
|
||||
class GameAdapter(private val activity: AppCompatActivity) :
|
||||
AbstractDiffAdapter<Game, GameAdapter.GameViewHolder>(exact = false) {
|
||||
|
||||
companion object {
|
||||
const val VIEW_TYPE_GRID = 0
|
||||
const val VIEW_TYPE_LIST = 1
|
||||
const val VIEW_TYPE_CAROUSEL = 2
|
||||
const val VIEW_TYPE_GRID_COMPACT = 1
|
||||
const val VIEW_TYPE_LIST = 2
|
||||
const val VIEW_TYPE_CAROUSEL = 3
|
||||
}
|
||||
|
||||
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.height = ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
}
|
||||
|
||||
VIEW_TYPE_GRID -> {
|
||||
val gridBinding = holder.binding as CardGameGridBinding
|
||||
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.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 -> {
|
||||
val carouselBinding = holder.binding as CardGameCarouselBinding
|
||||
// soothens transient flickering
|
||||
|
@ -105,16 +118,25 @@ class GameAdapter(private val activity: AppCompatActivity) :
|
|||
parent,
|
||||
false
|
||||
)
|
||||
|
||||
VIEW_TYPE_GRID -> CardGameGridBinding.inflate(
|
||||
LayoutInflater.from(parent.context),
|
||||
parent,
|
||||
false
|
||||
)
|
||||
|
||||
VIEW_TYPE_GRID_COMPACT -> CardGameGridCompactBinding.inflate(
|
||||
LayoutInflater.from(parent.context),
|
||||
parent,
|
||||
false
|
||||
)
|
||||
|
||||
VIEW_TYPE_CAROUSEL -> CardGameCarouselBinding.inflate(
|
||||
LayoutInflater.from(parent.context),
|
||||
parent,
|
||||
false
|
||||
)
|
||||
|
||||
else -> throw IllegalArgumentException("Invalid view type")
|
||||
}
|
||||
return GameViewHolder(binding, viewType)
|
||||
|
@ -130,6 +152,7 @@ class GameAdapter(private val activity: AppCompatActivity) :
|
|||
VIEW_TYPE_LIST -> bindListView(model)
|
||||
VIEW_TYPE_GRID -> bindGridView(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
|
||||
}
|
||||
|
||||
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) {
|
||||
val carouselBinding = binding as CardGameCarouselBinding
|
||||
|
||||
|
|
|
@ -194,6 +194,10 @@ class GamesFragment : Fragment() {
|
|||
val columns = resources.getInteger(R.integer.game_columns_grid)
|
||||
GridLayoutManager(context, columns)
|
||||
}
|
||||
GameAdapter.VIEW_TYPE_GRID_COMPACT -> {
|
||||
val columns = resources.getInteger(R.integer.game_columns_grid)
|
||||
GridLayoutManager(context, columns)
|
||||
}
|
||||
GameAdapter.VIEW_TYPE_LIST -> {
|
||||
val columns = resources.getInteger(R.integer.game_columns_list)
|
||||
GridLayoutManager(context, columns)
|
||||
|
@ -300,6 +304,7 @@ class GamesFragment : Fragment() {
|
|||
val currentViewType = getCurrentViewType()
|
||||
when (currentViewType) {
|
||||
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_CAROUSEL -> popup.menu.findItem(R.id.view_carousel).isChecked = true
|
||||
}
|
||||
|
@ -314,6 +319,14 @@ class GamesFragment : Fragment() {
|
|||
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 -> {
|
||||
if (getCurrentViewType() == GameAdapter.VIEW_TYPE_CAROUSEL) onPause()
|
||||
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>
|
|
@ -5,27 +5,32 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:focusable="false"
|
||||
android:focusableInTouchMode="false">
|
||||
android:focusableInTouchMode="false"
|
||||
android:padding="4dp">
|
||||
|
||||
<org.yuzu.yuzu_emu.views.GradientBorderCardView
|
||||
android:id="@+id/card_game_grid"
|
||||
app:cardElevation="0dp"
|
||||
app:cardBackgroundColor="@color/eden_card_background"
|
||||
app:strokeWidth="1dp"
|
||||
app:strokeColor="@color/eden_border"
|
||||
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"
|
||||
app:cardCornerRadius="16dp">
|
||||
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:padding="6dp">
|
||||
android:paddingTop="14dp"
|
||||
android:paddingLeft="6dp"
|
||||
android:paddingRight="6dp"
|
||||
android:paddingBottom="6dp">
|
||||
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
android:id="@+id/image_game_screen"
|
||||
|
|
|
@ -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
|
||||
android:id="@+id/view_grid"
|
||||
android:title="@string/view_grid"/>
|
||||
<item
|
||||
android:id="@+id/view_grid_compact"
|
||||
android:title="@string/view_grid_compact"/>
|
||||
<item
|
||||
android:id="@+id/view_list"
|
||||
android:title="@string/view_list"
|
||||
|
|
|
@ -266,6 +266,7 @@
|
|||
<string name="alphabetical">Alphabetical</string>
|
||||
<string name="view_list">List</string>
|
||||
<string name="view_grid">Grid</string>
|
||||
<string name="view_grid_compact">Compact Grid</string>
|
||||
<string name="view_carousel">Carousel</string>
|
||||
<string name="game_image_desc">Screenshot for %1$s</string>
|
||||
<string name="folder">Folder</string>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue