Browse Source
Refactor Android Game Screen UI
Refactor Android Game Screen UI
* Port SearchFragment functionality to GameFragment @kleidis Co-authored-by: Briar <205427297+icybriarr@users.noreply.github.com> * Remove the bottom navigation bar and SearchFragment remaining code @ishan09811 * Add 2 new game view types `Grid & `List` to GameAdapter @kleidis * Fix padding on header * Change app name to uppercase --------- Co-authored-by: Kleidis <167202775+kleidis@users.noreply.github.com> Co-authored-by: Briar <205427297+icybriarr@users.noreply.github.com> Co-authored-by: Ishan09811 <156402647+Ishan09811@users.noreply.github.com>pull/15/merge
committed by
GitHub
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
34 changed files with 717 additions and 692 deletions
-
76src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt
-
6src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/AboutFragment.kt
-
10src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/AddGameFolderDialogFragment.kt
-
5src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/AddonsFragment.kt
-
5src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/AppletLauncherFragment.kt
-
5src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/DriverManagerFragment.kt
-
5src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/GameFoldersFragment.kt
-
5src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/GameInfoFragment.kt
-
5src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/GamePropertiesFragment.kt
-
31src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/HomeSettingsFragment.kt
-
5src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/InstallableFragment.kt
-
6src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/LicensesFragment.kt
-
218src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SearchFragment.kt
-
5src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SetupFragment.kt
-
31src/android/app/src/main/java/org/yuzu/yuzu_emu/model/GamesViewModel.kt
-
12src/android/app/src/main/java/org/yuzu/yuzu_emu/model/HomeViewModel.kt
-
281src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/GamesFragment.kt
-
83src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt
-
9src/android/app/src/main/res/drawable/ic_eye.xml
-
9src/android/app/src/main/res/drawable/ic_filter.xml
-
12src/android/app/src/main/res/layout-w600dp/activity_main.xml
-
13src/android/app/src/main/res/layout/activity_main.xml
-
2src/android/app/src/main/res/layout/card_game_grid.xml
-
67src/android/app/src/main/res/layout/card_game_list.xml
-
231src/android/app/src/main/res/layout/fragment_games.xml
-
184src/android/app/src/main/res/layout/fragment_search.xml
-
19src/android/app/src/main/res/menu-w600dp/menu_navigation.xml
-
14src/android/app/src/main/res/menu/menu_game_filters.xml
-
12src/android/app/src/main/res/menu/menu_game_views.xml
-
19src/android/app/src/main/res/menu/menu_navigation.xml
-
12src/android/app/src/main/res/navigation/home_navigation.xml
-
3src/android/app/src/main/res/values-w600dp/integers.xml
-
2src/android/app/src/main/res/values/integers.xml
-
7src/android/app/src/main/res/values/strings.xml
@ -1,218 +0,0 @@ |
|||||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project |
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
|
|
||||
package org.yuzu.yuzu_emu.fragments |
|
||||
|
|
||||
import android.content.Context |
|
||||
import android.content.SharedPreferences |
|
||||
import android.os.Bundle |
|
||||
import android.view.LayoutInflater |
|
||||
import android.view.View |
|
||||
import android.view.ViewGroup |
|
||||
import android.view.inputmethod.InputMethodManager |
|
||||
import androidx.appcompat.app.AppCompatActivity |
|
||||
import androidx.core.view.ViewCompat |
|
||||
import androidx.core.view.WindowInsetsCompat |
|
||||
import androidx.core.view.updatePadding |
|
||||
import androidx.core.widget.doOnTextChanged |
|
||||
import androidx.fragment.app.Fragment |
|
||||
import androidx.fragment.app.activityViewModels |
|
||||
import androidx.preference.PreferenceManager |
|
||||
import info.debatty.java.stringsimilarity.Jaccard |
|
||||
import info.debatty.java.stringsimilarity.JaroWinkler |
|
||||
import java.util.Locale |
|
||||
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.FragmentSearchBinding |
|
||||
import org.yuzu.yuzu_emu.layout.AutofitGridLayoutManager |
|
||||
import org.yuzu.yuzu_emu.model.Game |
|
||||
import org.yuzu.yuzu_emu.model.GamesViewModel |
|
||||
import org.yuzu.yuzu_emu.model.HomeViewModel |
|
||||
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible |
|
||||
import org.yuzu.yuzu_emu.utils.collect |
|
||||
|
|
||||
class SearchFragment : Fragment() { |
|
||||
private var _binding: FragmentSearchBinding? = null |
|
||||
private val binding get() = _binding!! |
|
||||
|
|
||||
private val gamesViewModel: GamesViewModel by activityViewModels() |
|
||||
private val homeViewModel: HomeViewModel by activityViewModels() |
|
||||
|
|
||||
private lateinit var preferences: SharedPreferences |
|
||||
|
|
||||
companion object { |
|
||||
private const val SEARCH_TEXT = "SearchText" |
|
||||
} |
|
||||
|
|
||||
override fun onCreateView( |
|
||||
inflater: LayoutInflater, |
|
||||
container: ViewGroup?, |
|
||||
savedInstanceState: Bundle? |
|
||||
): View { |
|
||||
_binding = FragmentSearchBinding.inflate(layoutInflater) |
|
||||
return binding.root |
|
||||
} |
|
||||
|
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { |
|
||||
super.onViewCreated(view, savedInstanceState) |
|
||||
homeViewModel.setNavigationVisibility(visible = true, animated = true) |
|
||||
homeViewModel.setStatusBarShadeVisibility(true) |
|
||||
preferences = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext) |
|
||||
|
|
||||
if (savedInstanceState != null) { |
|
||||
binding.searchText.setText(savedInstanceState.getString(SEARCH_TEXT)) |
|
||||
} |
|
||||
|
|
||||
binding.gridGamesSearch.apply { |
|
||||
layoutManager = AutofitGridLayoutManager( |
|
||||
requireContext(), |
|
||||
requireContext().resources.getDimensionPixelSize(R.dimen.card_width) |
|
||||
) |
|
||||
adapter = GameAdapter(requireActivity() as AppCompatActivity) |
|
||||
} |
|
||||
|
|
||||
binding.chipGroup.setOnCheckedStateChangeListener { _, _ -> filterAndSearch() } |
|
||||
|
|
||||
binding.searchText.doOnTextChanged { text: CharSequence?, _: Int, _: Int, _: Int -> |
|
||||
binding.clearButton.setVisible(text.toString().isNotEmpty()) |
|
||||
filterAndSearch() |
|
||||
} |
|
||||
|
|
||||
gamesViewModel.searchFocused.collect( |
|
||||
viewLifecycleOwner, |
|
||||
resetState = { gamesViewModel.setSearchFocused(false) } |
|
||||
) { if (it) focusSearch() } |
|
||||
gamesViewModel.games.collect(viewLifecycleOwner) { filterAndSearch() } |
|
||||
gamesViewModel.searchedGames.collect(viewLifecycleOwner) { |
|
||||
(binding.gridGamesSearch.adapter as GameAdapter).submitList(it) |
|
||||
binding.noResultsView.setVisible(it.isNotEmpty()) |
|
||||
} |
|
||||
|
|
||||
binding.clearButton.setOnClickListener { binding.searchText.setText("") } |
|
||||
|
|
||||
binding.searchBackground.setOnClickListener { focusSearch() } |
|
||||
|
|
||||
setInsets() |
|
||||
filterAndSearch() |
|
||||
} |
|
||||
|
|
||||
private inner class ScoredGame(val score: Double, val item: Game) |
|
||||
|
|
||||
private fun filterAndSearch() { |
|
||||
val baseList = gamesViewModel.games.value |
|
||||
val filteredList: List<Game> = when (binding.chipGroup.checkedChipId) { |
|
||||
R.id.chip_recently_played -> { |
|
||||
baseList.filter { |
|
||||
val lastPlayedTime = preferences.getLong(it.keyLastPlayedTime, 0L) |
|
||||
lastPlayedTime > (System.currentTimeMillis() - 24 * 60 * 60 * 1000) |
|
||||
}.sortedByDescending { preferences.getLong(it.keyLastPlayedTime, 0L) } |
|
||||
} |
|
||||
|
|
||||
R.id.chip_recently_added -> { |
|
||||
baseList.filter { |
|
||||
val addedTime = preferences.getLong(it.keyAddedToLibraryTime, 0L) |
|
||||
addedTime > (System.currentTimeMillis() - 24 * 60 * 60 * 1000) |
|
||||
}.sortedByDescending { preferences.getLong(it.keyAddedToLibraryTime, 0L) } |
|
||||
} |
|
||||
|
|
||||
R.id.chip_homebrew -> baseList.filter { it.isHomebrew } |
|
||||
|
|
||||
R.id.chip_retail -> baseList.filter { !it.isHomebrew } |
|
||||
|
|
||||
else -> baseList |
|
||||
} |
|
||||
|
|
||||
if (binding.searchText.text.toString().isEmpty() && |
|
||||
binding.chipGroup.checkedChipId != View.NO_ID |
|
||||
) { |
|
||||
gamesViewModel.setSearchedGames(filteredList) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
val searchTerm = binding.searchText.text.toString().lowercase(Locale.getDefault()) |
|
||||
val searchAlgorithm = if (searchTerm.length > 1) Jaccard(2) else JaroWinkler() |
|
||||
val sortedList: List<Game> = filteredList.mapNotNull { game -> |
|
||||
val title = game.title.lowercase(Locale.getDefault()) |
|
||||
val score = searchAlgorithm.similarity(searchTerm, title) |
|
||||
if (score > 0.03) { |
|
||||
ScoredGame(score, game) |
|
||||
} else { |
|
||||
null |
|
||||
} |
|
||||
}.sortedByDescending { it.score }.map { it.item } |
|
||||
gamesViewModel.setSearchedGames(sortedList) |
|
||||
} |
|
||||
|
|
||||
override fun onDestroyView() { |
|
||||
super.onDestroyView() |
|
||||
_binding = null |
|
||||
} |
|
||||
|
|
||||
override fun onSaveInstanceState(outState: Bundle) { |
|
||||
super.onSaveInstanceState(outState) |
|
||||
if (_binding != null) { |
|
||||
outState.putString(SEARCH_TEXT, binding.searchText.text.toString()) |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private fun focusSearch() { |
|
||||
if (_binding != null) { |
|
||||
binding.searchText.requestFocus() |
|
||||
val imm = requireActivity() |
|
||||
.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager? |
|
||||
imm?.showSoftInput(binding.searchText, InputMethodManager.SHOW_IMPLICIT) |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private fun setInsets() = |
|
||||
ViewCompat.setOnApplyWindowInsetsListener( |
|
||||
binding.root |
|
||||
) { view: View, windowInsets: WindowInsetsCompat -> |
|
||||
val barInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) |
|
||||
val cutoutInsets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout()) |
|
||||
val extraListSpacing = resources.getDimensionPixelSize(R.dimen.spacing_med) |
|
||||
val spacingNavigation = resources.getDimensionPixelSize(R.dimen.spacing_navigation) |
|
||||
val spacingNavigationRail = |
|
||||
resources.getDimensionPixelSize(R.dimen.spacing_navigation_rail) |
|
||||
val chipSpacing = resources.getDimensionPixelSize(R.dimen.spacing_chip) |
|
||||
|
|
||||
binding.constraintSearch.updatePadding( |
|
||||
left = barInsets.left + cutoutInsets.left, |
|
||||
top = barInsets.top, |
|
||||
right = barInsets.right + cutoutInsets.right |
|
||||
) |
|
||||
|
|
||||
binding.gridGamesSearch.updatePadding( |
|
||||
top = extraListSpacing, |
|
||||
bottom = barInsets.bottom + spacingNavigation + extraListSpacing |
|
||||
) |
|
||||
binding.noResultsView.updatePadding(bottom = spacingNavigation + barInsets.bottom) |
|
||||
|
|
||||
val mlpDivider = binding.divider.layoutParams as ViewGroup.MarginLayoutParams |
|
||||
if (ViewCompat.getLayoutDirection(view) == ViewCompat.LAYOUT_DIRECTION_LTR) { |
|
||||
binding.frameSearch.updatePadding(left = spacingNavigationRail) |
|
||||
binding.gridGamesSearch.updatePadding(left = spacingNavigationRail) |
|
||||
binding.noResultsView.updatePadding(left = spacingNavigationRail) |
|
||||
binding.chipGroup.updatePadding( |
|
||||
left = chipSpacing + spacingNavigationRail, |
|
||||
right = chipSpacing |
|
||||
) |
|
||||
mlpDivider.leftMargin = chipSpacing + spacingNavigationRail |
|
||||
mlpDivider.rightMargin = chipSpacing |
|
||||
} else { |
|
||||
binding.frameSearch.updatePadding(right = spacingNavigationRail) |
|
||||
binding.gridGamesSearch.updatePadding(right = spacingNavigationRail) |
|
||||
binding.noResultsView.updatePadding(right = spacingNavigationRail) |
|
||||
binding.chipGroup.updatePadding( |
|
||||
left = chipSpacing, |
|
||||
right = chipSpacing + spacingNavigationRail |
|
||||
) |
|
||||
mlpDivider.leftMargin = chipSpacing |
|
||||
mlpDivider.rightMargin = chipSpacing + spacingNavigationRail |
|
||||
} |
|
||||
binding.divider.layoutParams = mlpDivider |
|
||||
|
|
||||
windowInsets |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,9 @@ |
|||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" |
||||
|
android:width="24dp" |
||||
|
android:height="24dp" |
||||
|
android:viewportWidth="24" |
||||
|
android:viewportHeight="24"> |
||||
|
<path |
||||
|
android:fillColor="#000000" |
||||
|
android:pathData="M12,4.5C7.05,4.5 2.73,7.61 1,12c1.73,4.39 6.05,7.5 11,7.5s9.27,-3.11 11,-7.5c-1.73,-4.39 -6.05,-7.5 -11,-7.5zM12,17c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5zM12,8c-2.21,0 -4,1.79 -4,4s1.79,4 4,4 4,-1.79 4,-4 -1.79,-4 -4,-4z"/> |
||||
|
</vector> |
||||
@ -0,0 +1,9 @@ |
|||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" |
||||
|
android:width="24dp" |
||||
|
android:height="24dp" |
||||
|
android:viewportWidth="24" |
||||
|
android:viewportHeight="24"> |
||||
|
<path |
||||
|
android:fillColor="?attr/colorControlNormal" |
||||
|
android:pathData="M10,18h4v-2h-4v2zM3,6v2h18L21,6L3,6zM6,13h12v-2L6,11v2z"/> |
||||
|
</vector> |
||||
@ -0,0 +1,67 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<com.google.android.material.card.MaterialCardView 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:id="@+id/card_game_list" |
||||
|
style="?attr/materialCardViewStyle" |
||||
|
android:layout_width="match_parent" |
||||
|
android:layout_height="wrap_content" |
||||
|
android:layout_margin="8dp" |
||||
|
android:background="?attr/selectableItemBackground" |
||||
|
android:clickable="true" |
||||
|
android:focusable="true" |
||||
|
android:transitionName="card_game" |
||||
|
app:cardCornerRadius="14dp" |
||||
|
app:cardElevation="0dp"> |
||||
|
|
||||
|
<androidx.constraintlayout.widget.ConstraintLayout |
||||
|
android:layout_width="match_parent" |
||||
|
android:layout_height="wrap_content" |
||||
|
android:padding="8dp"> |
||||
|
|
||||
|
<com.google.android.material.imageview.ShapeableImageView |
||||
|
android:id="@+id/image_game_screen" |
||||
|
android:layout_width="66dp" |
||||
|
android:layout_height="66dp" |
||||
|
app:layout_constraintBottom_toBottomOf="parent" |
||||
|
app:layout_constraintStart_toStartOf="parent" |
||||
|
app:layout_constraintTop_toTopOf="parent" |
||||
|
app:shapeAppearance="@style/ShapeAppearance.Material3.Corner.Medium" |
||||
|
tools:src="@drawable/default_icon" /> |
||||
|
|
||||
|
<com.google.android.material.textview.MaterialTextView |
||||
|
android:id="@+id/text_game_title" |
||||
|
style="@style/TextAppearance.Material3.TitleMedium" |
||||
|
android:layout_width="0dp" |
||||
|
android:layout_height="wrap_content" |
||||
|
android:layout_marginStart="8dp" |
||||
|
android:requiresFadingEdge="horizontal" |
||||
|
android:textAlignment="viewStart" |
||||
|
android:singleLine="true" |
||||
|
android:textSize="14sp" |
||||
|
app:layout_constraintBottom_toTopOf="@+id/text_game_developer" |
||||
|
app:layout_constraintEnd_toEndOf="parent" |
||||
|
app:layout_constraintStart_toEndOf="@+id/image_game_screen" |
||||
|
app:layout_constraintTop_toTopOf="parent" |
||||
|
app:layout_constraintVertical_chainStyle="packed" |
||||
|
tools:text="The Legend of Zelda: Skyward Sword" /> |
||||
|
|
||||
|
<com.google.android.material.textview.MaterialTextView |
||||
|
android:id="@+id/text_game_developer" |
||||
|
style="@style/TextAppearance.Material3.BodySmall" |
||||
|
android:layout_width="0dp" |
||||
|
android:layout_height="wrap_content" |
||||
|
android:layout_marginStart="8dp" |
||||
|
android:requiresFadingEdge="horizontal" |
||||
|
android:textAlignment="viewStart" |
||||
|
android:singleLine="true" |
||||
|
android:textSize="12sp" |
||||
|
app:layout_constraintBottom_toBottomOf="parent" |
||||
|
app:layout_constraintEnd_toEndOf="parent" |
||||
|
app:layout_constraintStart_toEndOf="@+id/image_game_screen" |
||||
|
app:layout_constraintTop_toBottomOf="@+id/text_game_title" |
||||
|
tools:text="Generic" /> |
||||
|
|
||||
|
</androidx.constraintlayout.widget.ConstraintLayout> |
||||
|
|
||||
|
</com.google.android.material.card.MaterialCardView> |
||||
@ -1,35 +1,224 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout |
|
||||
|
<androidx.constraintlayout.widget.ConstraintLayout |
||||
|
|
||||
xmlns:android="http://schemas.android.com/apk/res/android" |
xmlns:android="http://schemas.android.com/apk/res/android" |
||||
xmlns:tools="http://schemas.android.com/tools" |
|
||||
android:id="@+id/swipe_refresh" |
|
||||
|
xmlns:app="http://schemas.android.com/apk/res-auto" |
||||
android:layout_width="match_parent" |
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
android:layout_height="match_parent" |
||||
android:background="?attr/colorSurface" |
android:background="?attr/colorSurface" |
||||
android:clipToPadding="false"> |
|
||||
|
> |
||||
|
|
||||
<RelativeLayout |
|
||||
|
<LinearLayout |
||||
|
android:id="@+id/header" |
||||
android:layout_width="match_parent" |
android:layout_width="match_parent" |
||||
android:layout_height="match_parent"> |
|
||||
|
android:layout_height="wrap_content" |
||||
|
android:orientation="horizontal" |
||||
|
android:layout_marginHorizontal="20dp" |
||||
|
app:layout_constraintTop_toTopOf="parent" |
||||
|
> |
||||
|
|
||||
<com.google.android.material.textview.MaterialTextView |
<com.google.android.material.textview.MaterialTextView |
||||
android:id="@+id/notice_text" |
|
||||
style="@style/TextAppearance.Material3.BodyLarge" |
|
||||
|
android:id="@+id/title" |
||||
|
android:layout_width="wrap_content" |
||||
|
android:layout_height="wrap_content" |
||||
|
android:text="@string/app_name" |
||||
|
android:textAppearance="@style/TextAppearance.Material3.HeadlineLarge" |
||||
|
android:textSize="27sp" |
||||
|
android:textStyle="bold" |
||||
|
/> |
||||
|
|
||||
|
<Space |
||||
|
android:layout_width="0dp" |
||||
|
android:layout_height="wrap_content" |
||||
|
android:layout_weight="1" |
||||
|
/> |
||||
|
|
||||
|
<com.google.android.material.card.MaterialCardView |
||||
|
android:id="@+id/view_button" |
||||
|
style="?attr/materialCardViewFilledStyle" |
||||
|
android:layout_width="42dp" |
||||
|
android:layout_height="42dp" |
||||
|
app:cardCornerRadius="21dp" |
||||
|
> |
||||
|
|
||||
|
<ImageView |
||||
|
android:layout_width="18dp" |
||||
|
android:layout_height="18dp" |
||||
|
android:layout_gravity="center" |
||||
|
android:src="@drawable/ic_eye" |
||||
|
app:tint="?attr/colorOnSurfaceVariant" |
||||
|
/> |
||||
|
|
||||
|
</com.google.android.material.card.MaterialCardView> |
||||
|
|
||||
|
<Space |
||||
|
android:layout_width="15dp" |
||||
|
android:layout_height="wrap_content" |
||||
|
/> |
||||
|
|
||||
|
<com.google.android.material.card.MaterialCardView |
||||
|
android:id="@+id/filter_button" |
||||
|
style="?attr/materialCardViewFilledStyle" |
||||
|
android:layout_width="42dp" |
||||
|
android:layout_height="42dp" |
||||
|
app:cardCornerRadius="21dp" |
||||
|
> |
||||
|
|
||||
|
<ImageView |
||||
|
android:layout_width="18dp" |
||||
|
android:layout_height="18dp" |
||||
|
android:layout_gravity="center" |
||||
|
android:src="@drawable/ic_filter" |
||||
|
app:tint="?attr/colorOnSurfaceVariant" |
||||
|
/> |
||||
|
|
||||
|
</com.google.android.material.card.MaterialCardView> |
||||
|
|
||||
|
<Space |
||||
|
android:layout_width="15dp" |
||||
|
android:layout_height="wrap_content" |
||||
|
/> |
||||
|
|
||||
|
<com.google.android.material.card.MaterialCardView |
||||
|
android:id="@+id/settings_button" |
||||
|
style="?attr/materialCardViewFilledStyle" |
||||
|
android:layout_width="42dp" |
||||
|
android:layout_height="42dp" |
||||
|
app:cardCornerRadius="21dp" |
||||
|
> |
||||
|
|
||||
|
<ImageView |
||||
|
android:layout_width="18dp" |
||||
|
android:layout_height="18dp" |
||||
|
android:layout_gravity="center" |
||||
|
android:src="@drawable/ic_settings" |
||||
|
app:tint="?attr/colorOnSurfaceVariant" |
||||
|
/> |
||||
|
|
||||
|
</com.google.android.material.card.MaterialCardView> |
||||
|
|
||||
|
</LinearLayout> |
||||
|
|
||||
|
<FrameLayout |
||||
|
android:id="@+id/frame_search" |
||||
|
android:layout_width="0dp" |
||||
|
android:layout_height="wrap_content" |
||||
|
android:layout_marginTop="16dp" |
||||
|
android:layout_marginHorizontal="15dp" |
||||
|
app:layout_constraintStart_toStartOf="parent" |
||||
|
app:layout_constraintEnd_toEndOf="parent" |
||||
|
app:layout_constraintTop_toBottomOf="@id/header" |
||||
|
> |
||||
|
|
||||
|
<com.google.android.material.card.MaterialCardView |
||||
|
android:id="@+id/search_background" |
||||
|
style="?attr/materialCardViewFilledStyle" |
||||
android:layout_width="match_parent" |
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
|
||||
android:gravity="center" |
|
||||
android:padding="@dimen/spacing_large" |
|
||||
android:text="@string/empty_gamelist" |
|
||||
android:visibility="gone" /> |
|
||||
|
android:layout_height="48dp" |
||||
|
app:cardCornerRadius="21dp" |
||||
|
> |
||||
|
|
||||
|
<LinearLayout |
||||
|
android:id="@+id/search_container" |
||||
|
android:layout_width="match_parent" |
||||
|
android:layout_height="match_parent" |
||||
|
android:layout_marginStart="18dp" |
||||
|
android:layout_marginEnd="42dp" |
||||
|
android:orientation="horizontal" |
||||
|
> |
||||
|
|
||||
|
<ImageView |
||||
|
android:layout_width="21dp" |
||||
|
android:layout_height="21dp" |
||||
|
android:layout_gravity="center_vertical" |
||||
|
android:layout_marginEnd="18dp" |
||||
|
android:src="@drawable/ic_search" |
||||
|
app:tint="?attr/colorOnSurfaceVariant" |
||||
|
/> |
||||
|
|
||||
|
<EditText |
||||
|
android:id="@+id/search_text" |
||||
|
android:layout_width="match_parent" |
||||
|
android:layout_height="match_parent" |
||||
|
android:background="@android:color/transparent" |
||||
|
android:hint="@string/home_search_games" |
||||
|
android:inputType="text" |
||||
|
android:maxLines="1" |
||||
|
android:imeOptions="flagNoFullscreen" |
||||
|
/> |
||||
|
|
||||
|
</LinearLayout> |
||||
|
|
||||
|
<ImageView |
||||
|
android:id="@+id/clear_button" |
||||
|
android:layout_width="18dp" |
||||
|
android:layout_height="18dp" |
||||
|
android:layout_gravity="center_vertical|end" |
||||
|
android:layout_marginEnd="18dp" |
||||
|
android:background="?attr/selectableItemBackground" |
||||
|
android:src="@drawable/ic_clear" |
||||
|
android:visibility="invisible" |
||||
|
app:tint="?attr/colorOnSurfaceVariant" |
||||
|
/> |
||||
|
|
||||
|
</com.google.android.material.card.MaterialCardView> |
||||
|
|
||||
|
</FrameLayout> |
||||
|
|
||||
<androidx.recyclerview.widget.RecyclerView |
|
||||
android:id="@+id/grid_games" |
|
||||
|
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout |
||||
|
android:id="@+id/swipe_refresh" |
||||
|
android:layout_width="match_parent" |
||||
|
android:layout_height="0dp" |
||||
|
android:layout_marginTop="8dp" |
||||
|
app:layout_constraintTop_toBottomOf="@id/frame_search" |
||||
|
app:layout_constraintBottom_toBottomOf="parent" |
||||
|
> |
||||
|
|
||||
|
<RelativeLayout |
||||
android:layout_width="match_parent" |
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
android:layout_height="match_parent" |
||||
android:clipToPadding="false" |
|
||||
android:defaultFocusHighlightEnabled="false" |
|
||||
tools:listitem="@layout/card_game" /> |
|
||||
|
> |
||||
|
|
||||
|
<com.google.android.material.textview.MaterialTextView |
||||
|
android:id="@+id/notice_text" |
||||
|
style="@style/TextAppearance.Material3.BodyLarge" |
||||
|
android:layout_width="match_parent" |
||||
|
android:layout_height="match_parent" |
||||
|
android:gravity="center" |
||||
|
android:padding="@dimen/spacing_large" |
||||
|
android:text="@string/empty_gamelist" |
||||
|
android:visibility="gone" |
||||
|
/> |
||||
|
|
||||
|
<androidx.recyclerview.widget.RecyclerView |
||||
|
android:id="@+id/grid_games" |
||||
|
android:layout_width="match_parent" |
||||
|
android:layout_height="match_parent" |
||||
|
android:clipToPadding="false" |
||||
|
android:scrollbarStyle="outsideOverlay" |
||||
|
android:scrollbars="vertical" |
||||
|
android:fadeScrollbars="true" |
||||
|
android:paddingHorizontal="4dp" |
||||
|
android:paddingVertical="4dp" |
||||
|
/> |
||||
|
|
||||
|
|
||||
|
</RelativeLayout> |
||||
|
|
||||
|
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout> |
||||
|
|
||||
</RelativeLayout> |
|
||||
|
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton |
||||
|
android:id="@+id/add_directory" |
||||
|
android:layout_width="wrap_content" |
||||
|
android:layout_height="wrap_content" |
||||
|
android:layout_margin="16dp" |
||||
|
android:contentDescription="Select_game_folder" |
||||
|
android:text="@string/folder" |
||||
|
app:icon="@drawable/ic_cartridge_outline" |
||||
|
app:layout_constraintBottom_toBottomOf="parent" |
||||
|
app:layout_constraintEnd_toEndOf="parent" |
||||
|
android:textColor="?attr/colorOnPrimaryContainer" |
||||
|
app:backgroundTint="?attr/colorPrimaryContainer" |
||||
|
app:iconTint="?attr/colorOnPrimaryContainer" |
||||
|
/> |
||||
|
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout> |
|
||||
|
</androidx.constraintlayout.widget.ConstraintLayout> |
||||
@ -1,184 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<androidx.constraintlayout.widget.ConstraintLayout |
|
||||
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:id="@+id/constraint_search" |
|
||||
android:layout_width="match_parent" |
|
||||
android:layout_height="match_parent" |
|
||||
android:background="?attr/colorSurface" |
|
||||
android:clipToPadding="false"> |
|
||||
|
|
||||
<RelativeLayout |
|
||||
android:layout_width="0dp" |
|
||||
android:layout_height="0dp" |
|
||||
app:layout_constraintBottom_toBottomOf="parent" |
|
||||
app:layout_constraintEnd_toEndOf="parent" |
|
||||
app:layout_constraintStart_toStartOf="parent" |
|
||||
app:layout_constraintTop_toBottomOf="@+id/divider"> |
|
||||
|
|
||||
<LinearLayout |
|
||||
android:id="@+id/no_results_view" |
|
||||
android:layout_width="match_parent" |
|
||||
android:layout_height="match_parent" |
|
||||
android:orientation="vertical" |
|
||||
android:gravity="center"> |
|
||||
|
|
||||
<ImageView |
|
||||
android:id="@+id/icon_no_results" |
|
||||
android:layout_width="match_parent" |
|
||||
android:layout_height="80dp" |
|
||||
android:src="@drawable/ic_search" /> |
|
||||
|
|
||||
<com.google.android.material.textview.MaterialTextView |
|
||||
android:id="@+id/notice_text" |
|
||||
style="@style/TextAppearance.Material3.TitleLarge" |
|
||||
android:layout_width="match_parent" |
|
||||
android:layout_height="wrap_content" |
|
||||
android:gravity="center" |
|
||||
android:paddingTop="8dp" |
|
||||
android:text="@string/search_and_filter_games" |
|
||||
tools:visibility="visible" /> |
|
||||
|
|
||||
</LinearLayout> |
|
||||
|
|
||||
<androidx.recyclerview.widget.RecyclerView |
|
||||
android:id="@+id/grid_games_search" |
|
||||
android:layout_width="match_parent" |
|
||||
android:layout_height="match_parent" |
|
||||
android:clipToPadding="false" /> |
|
||||
|
|
||||
</RelativeLayout> |
|
||||
|
|
||||
<FrameLayout |
|
||||
android:id="@+id/frame_search" |
|
||||
android:layout_width="match_parent" |
|
||||
android:layout_height="wrap_content" |
|
||||
android:layout_marginTop="12dp" |
|
||||
android:layout_marginHorizontal="20dp" |
|
||||
app:layout_constraintEnd_toEndOf="parent" |
|
||||
app:layout_constraintStart_toStartOf="parent" |
|
||||
app:layout_constraintTop_toTopOf="parent"> |
|
||||
|
|
||||
<com.google.android.material.card.MaterialCardView |
|
||||
android:id="@+id/search_background" |
|
||||
style="?attr/materialCardViewFilledStyle" |
|
||||
android:layout_width="match_parent" |
|
||||
android:layout_height="56dp" |
|
||||
app:cardCornerRadius="28dp"> |
|
||||
|
|
||||
<LinearLayout |
|
||||
android:id="@+id/search_container" |
|
||||
android:layout_width="match_parent" |
|
||||
android:layout_height="match_parent" |
|
||||
android:layout_marginStart="24dp" |
|
||||
android:layout_marginEnd="56dp" |
|
||||
android:orientation="horizontal"> |
|
||||
|
|
||||
<ImageView |
|
||||
android:layout_width="28dp" |
|
||||
android:layout_height="28dp" |
|
||||
android:layout_gravity="center_vertical" |
|
||||
android:layout_marginEnd="24dp" |
|
||||
android:src="@drawable/ic_search" |
|
||||
app:tint="?attr/colorOnSurfaceVariant" /> |
|
||||
|
|
||||
<EditText |
|
||||
android:id="@+id/search_text" |
|
||||
android:layout_width="match_parent" |
|
||||
android:layout_height="match_parent" |
|
||||
android:background="@android:color/transparent" |
|
||||
android:hint="@string/home_search_games" |
|
||||
android:inputType="text" |
|
||||
android:maxLines="1" |
|
||||
android:imeOptions="flagNoFullscreen" /> |
|
||||
|
|
||||
</LinearLayout> |
|
||||
|
|
||||
<ImageView |
|
||||
android:id="@+id/clear_button" |
|
||||
android:layout_width="24dp" |
|
||||
android:layout_height="24dp" |
|
||||
android:layout_gravity="center_vertical|end" |
|
||||
android:layout_marginEnd="24dp" |
|
||||
android:background="?attr/selectableItemBackground" |
|
||||
android:src="@drawable/ic_clear" |
|
||||
android:visibility="invisible" |
|
||||
app:tint="?attr/colorOnSurfaceVariant" |
|
||||
tools:visibility="visible" /> |
|
||||
|
|
||||
</com.google.android.material.card.MaterialCardView> |
|
||||
|
|
||||
</FrameLayout> |
|
||||
|
|
||||
<HorizontalScrollView |
|
||||
android:id="@+id/horizontalScrollView" |
|
||||
android:layout_width="match_parent" |
|
||||
android:layout_height="wrap_content" |
|
||||
android:fadingEdge="horizontal" |
|
||||
android:scrollbars="none" |
|
||||
app:layout_constraintEnd_toEndOf="parent" |
|
||||
app:layout_constraintStart_toStartOf="parent" |
|
||||
app:layout_constraintTop_toBottomOf="@+id/frame_search"> |
|
||||
|
|
||||
<com.google.android.material.chip.ChipGroup |
|
||||
android:id="@+id/chip_group" |
|
||||
android:layout_width="wrap_content" |
|
||||
android:layout_height="wrap_content" |
|
||||
android:clipToPadding="false" |
|
||||
android:paddingVertical="4dp" |
|
||||
app:checkedChip="@id/chip_recently_played" |
|
||||
app:chipSpacingHorizontal="12dp" |
|
||||
app:singleLine="true" |
|
||||
app:singleSelection="true"> |
|
||||
|
|
||||
<com.google.android.material.chip.Chip |
|
||||
android:id="@+id/chip_recently_played" |
|
||||
style="@style/Widget.Material3.Chip.Suggestion.Elevated" |
|
||||
android:layout_width="wrap_content" |
|
||||
android:layout_height="wrap_content" |
|
||||
android:checked="false" |
|
||||
android:text="@string/search_recently_played" |
|
||||
app:chipCornerRadius="28dp" /> |
|
||||
|
|
||||
<com.google.android.material.chip.Chip |
|
||||
android:id="@+id/chip_recently_added" |
|
||||
style="@style/Widget.Material3.Chip.Suggestion.Elevated" |
|
||||
android:layout_width="wrap_content" |
|
||||
android:layout_height="wrap_content" |
|
||||
android:checked="false" |
|
||||
android:text="@string/search_recently_added" |
|
||||
app:chipCornerRadius="28dp" /> |
|
||||
|
|
||||
<com.google.android.material.chip.Chip |
|
||||
android:id="@+id/chip_retail" |
|
||||
style="@style/Widget.Material3.Chip.Suggestion.Elevated" |
|
||||
android:layout_width="wrap_content" |
|
||||
android:layout_height="wrap_content" |
|
||||
android:checked="false" |
|
||||
android:text="@string/search_retail" |
|
||||
app:chipCornerRadius="28dp" /> |
|
||||
|
|
||||
<com.google.android.material.chip.Chip |
|
||||
android:id="@+id/chip_homebrew" |
|
||||
style="@style/Widget.Material3.Chip.Suggestion.Elevated" |
|
||||
android:layout_width="wrap_content" |
|
||||
android:layout_height="wrap_content" |
|
||||
android:checked="false" |
|
||||
android:text="@string/search_homebrew" |
|
||||
app:chipCornerRadius="28dp" /> |
|
||||
|
|
||||
</com.google.android.material.chip.ChipGroup> |
|
||||
|
|
||||
</HorizontalScrollView> |
|
||||
|
|
||||
<com.google.android.material.divider.MaterialDivider |
|
||||
android:id="@+id/divider" |
|
||||
android:layout_width="match_parent" |
|
||||
android:layout_height="wrap_content" |
|
||||
android:layout_marginHorizontal="20dp" |
|
||||
app:layout_constraintEnd_toEndOf="parent" |
|
||||
app:layout_constraintStart_toStartOf="parent" |
|
||||
app:layout_constraintTop_toBottomOf="@+id/horizontalScrollView" /> |
|
||||
|
|
||||
</androidx.constraintlayout.widget.ConstraintLayout> |
|
||||
@ -1,19 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"> |
|
||||
|
|
||||
<item |
|
||||
android:id="@+id/homeSettingsFragment" |
|
||||
android:icon="@drawable/selector_settings" |
|
||||
android:title="@string/home_settings" /> |
|
||||
|
|
||||
<item |
|
||||
android:id="@+id/searchFragment" |
|
||||
android:icon="@drawable/ic_search" |
|
||||
android:title="@string/home_search" /> |
|
||||
|
|
||||
<item |
|
||||
android:id="@+id/gamesFragment" |
|
||||
android:icon="@drawable/selector_cartridge" |
|
||||
android:title="@string/home_games" /> |
|
||||
|
|
||||
</menu> |
|
||||
@ -0,0 +1,14 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"> |
||||
|
<group android:checkableBehavior="single"> |
||||
|
<item android:id="@+id/alphabetical" |
||||
|
android:title="@string/alphabetical" |
||||
|
android:checked="true"/> |
||||
|
<item |
||||
|
android:id="@+id/filter_recently_played" |
||||
|
android:title="@string/search_recently_played" /> |
||||
|
<item |
||||
|
android:id="@+id/filter_recently_added" |
||||
|
android:title="@string/search_recently_added" /> |
||||
|
</group> |
||||
|
</menu> |
||||
@ -0,0 +1,12 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"> |
||||
|
<group android:checkableBehavior="single"> |
||||
|
<item |
||||
|
android:id="@+id/view_grid" |
||||
|
android:title="@string/view_grid"/> |
||||
|
<item |
||||
|
android:id="@+id/view_list" |
||||
|
android:title="@string/view_list" |
||||
|
android:checked="true"/> |
||||
|
</group> |
||||
|
</menu> |
||||
@ -1,19 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"> |
|
||||
|
|
||||
<item |
|
||||
android:id="@+id/gamesFragment" |
|
||||
android:icon="@drawable/selector_cartridge" |
|
||||
android:title="@string/home_games" /> |
|
||||
|
|
||||
<item |
|
||||
android:id="@+id/searchFragment" |
|
||||
android:icon="@drawable/ic_search" |
|
||||
android:title="@string/home_search" /> |
|
||||
|
|
||||
<item |
|
||||
android:id="@+id/homeSettingsFragment" |
|
||||
android:icon="@drawable/selector_settings" |
|
||||
android:title="@string/home_settings" /> |
|
||||
|
|
||||
</menu> |
|
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue