From c9dcb070ad0bdce54f20d767f4d75ce4c1497371 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=97=B1=20PixelyIon?= Date: Sun, 12 Apr 2020 20:47:51 +0530 Subject: [PATCH] Grid Layout Support With `RecyclerView` being used rather than `ListView` or `GridView`. It's now possible to display the items in a flexible manner and so support for a grid view in addition to the already existing list view was added in. --- app/src/main/java/emu/skyline/MainActivity.kt | 34 +++++++---- .../java/emu/skyline/adapter/AppAdapter.kt | 33 +++++++---- .../java/emu/skyline/adapter/HeaderAdapter.kt | 19 +++++++ app/src/main/res/layout/app_item_grid.xml | 56 +++++++++++++++++++ app/src/main/res/values/array.xml | 8 +++ app/src/main/res/values/strings.xml | 2 +- app/src/main/res/xml/preferences.xml | 7 +++ 7 files changed, 136 insertions(+), 23 deletions(-) create mode 100644 app/src/main/res/layout/app_item_grid.xml diff --git a/app/src/main/java/emu/skyline/MainActivity.kt b/app/src/main/java/emu/skyline/MainActivity.kt index eeaa28d0..a23eb85d 100644 --- a/app/src/main/java/emu/skyline/MainActivity.kt +++ b/app/src/main/java/emu/skyline/MainActivity.kt @@ -19,11 +19,14 @@ import androidx.appcompat.widget.SearchView import androidx.documentfile.provider.DocumentFile import androidx.preference.PreferenceManager import androidx.recyclerview.widget.DividerItemDecoration +import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.google.android.material.snackbar.Snackbar import emu.skyline.adapter.AppAdapter import emu.skyline.adapter.AppItem +import emu.skyline.adapter.GridLayoutSpan +import emu.skyline.adapter.LayoutType import emu.skyline.loader.BaseLoader import emu.skyline.loader.NroLoader import emu.skyline.utility.GameDialog @@ -32,6 +35,7 @@ import kotlinx.android.synthetic.main.main_activity.* import java.io.File import java.io.IOException import kotlin.concurrent.thread +import kotlin.math.ceil class MainActivity : AppCompatActivity(), View.OnClickListener { private lateinit var sharedPreferences: SharedPreferences @@ -131,23 +135,31 @@ class MainActivity : AppCompatActivity(), View.OnClickListener { setSupportActionBar(toolbar) open_fab.setOnClickListener(this) log_fab.setOnClickListener(this) - adapter = AppAdapter(this) + + val layoutType = LayoutType.values()[sharedPreferences.getString("layout_type", "1")!!.toInt()] + + adapter = AppAdapter(this, layoutType) app_list.adapter = adapter - app_list.layoutManager = LinearLayoutManager(this) - app_list.addItemDecoration(DividerItemDecoration(this, RecyclerView.VERTICAL)) - - startActivity(intent) + when (layoutType) { + LayoutType.List -> { + app_list.layoutManager = LinearLayoutManager(this) + app_list.addItemDecoration(DividerItemDecoration(this, RecyclerView.VERTICAL)) } - } - game_list.onItemLongClickListener = AdapterView.OnItemLongClickListener { parent, _, position, _ -> - val item = parent.getItemAtPosition(position) - if (item is AppItem) { - val dialog = GameDialog(item) - dialog.show(supportFragmentManager, "game") + + LayoutType.Grid -> { + val itemWidth = 225 + val metrics = resources.displayMetrics + val span = ceil((metrics.widthPixels / metrics.density) / itemWidth).toInt() + + val layoutManager = GridLayoutManager(this, span) + layoutManager.spanSizeLookup = GridLayoutSpan(adapter, span) + + app_list.layoutManager = layoutManager } true } + if (sharedPreferences.getString("search_location", "") == "") { val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE) intent.flags = Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION or Intent.FLAG_GRANT_PREFIX_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION diff --git a/app/src/main/java/emu/skyline/adapter/AppAdapter.kt b/app/src/main/java/emu/skyline/adapter/AppAdapter.kt index 27f175ce..6186b1ad 100644 --- a/app/src/main/java/emu/skyline/adapter/AppAdapter.kt +++ b/app/src/main/java/emu/skyline/adapter/AppAdapter.kt @@ -67,18 +67,19 @@ class AppItem(val meta: AppEntry) : BaseItem() { } } +/** + * This enumerates the type of layouts the menu can be in + */ +enum class LayoutType { + List, + Grid, +} + /** * This adapter is used to display all found applications using their metadata */ -internal class AppAdapter(val context: Context?) : HeaderAdapter(), View.OnClickListener { - /** - * The icon to use on items that don't have a valid icon - */ +internal class AppAdapter(val context: Context?, private val layoutType: LayoutType) : HeaderAdapter(), View.OnClickListener { private val missingIcon = context?.resources?.getDrawable(R.drawable.default_icon, context.theme)?.toBitmap(256, 256) - - /** - * The string to use as a description for items that don't have a valid description - */ private val missingString = context?.getString(R.string.metadata_missing) /** @@ -137,7 +138,7 @@ internal class AppAdapter(val context: Context?) : HeaderAdapter(val adapter: HeaderAdapter, var headerSpan: Int) : GridLayoutManager.SpanSizeLookup() { + /** + * This returns the size of the span based on the type of the element at [position] + */ + override fun getSpanSize(position: Int): Int { + val item = adapter.getItem(position)!! + return if (item.elementType == ElementType.Item) + 1 + else + headerSpan + } +} diff --git a/app/src/main/res/layout/app_item_grid.xml b/app/src/main/res/layout/app_item_grid.xml new file mode 100644 index 00000000..720fe7c5 --- /dev/null +++ b/app/src/main/res/layout/app_item_grid.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values/array.xml b/app/src/main/res/values/array.xml index b50b0623..37bc2d27 100644 --- a/app/src/main/res/values/array.xml +++ b/app/src/main/res/values/array.xml @@ -12,6 +12,14 @@ 2 3 + + List + Grid + + + 0 + 1 + Light Dark diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 69f75aeb..74b6539f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -33,7 +33,7 @@ The system will emulate being in handheld mode The system will emulate being in docked mode Theme - Searching for ROMs + Application Layout Audio Audio Buffer Size The size of the buffer used to store audio samples for ROMs using audren. A lower value will result in less latency but potentially increased audio stutter depending on the performance of the device diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 3ba57de2..79a96a6a 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -30,6 +30,13 @@ app:key="app_theme" app:title="@string/theme" app:useSimpleSummaryProvider="true" /> +