Improvements to UI/UX

This commit makes a few improvements to the UI/UX:
* Crop Game Icons to ImageView
* Controller Support for Game List
* EmulationActivity is fullscreen now
This commit is contained in:
◱ PixelyIon 2020-04-24 17:09:13 +05:30
parent f909c00e31
commit 4d787c904e
22 changed files with 232 additions and 182 deletions

View File

@ -2,7 +2,7 @@
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
-keep class emu.skyline.loader.TitleEntry {
-keep class emu.skyline.loader.AppEntry {
void writeObject(java.io.ObjectOutputStream);
void readObject(java.io.ObjectInputStream);
}

View File

@ -3,7 +3,7 @@
* Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
*/
package emu.skyline.utility
package emu.skyline
import android.content.ComponentName
import android.content.Intent
@ -11,14 +11,13 @@ import android.content.pm.ShortcutInfo
import android.content.pm.ShortcutManager
import android.graphics.drawable.Icon
import android.os.Bundle
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.graphics.drawable.toBitmap
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import emu.skyline.EmulationActivity
import emu.skyline.R
import emu.skyline.adapter.AppItem
import kotlinx.android.synthetic.main.app_dialog.*
@ -37,13 +36,22 @@ class AppDialog(val item: AppItem? = null) : BottomSheetDialogFragment() {
}
/**
* This expands the bottom sheet so that it's fully visible
* This expands the bottom sheet so that it's fully visible and map the B button to back
*/
override fun onStart() {
super.onStart()
val behavior = BottomSheetBehavior.from(requireView().parent as View)
behavior.state = BottomSheetBehavior.STATE_EXPANDED
dialog?.setOnKeyListener { _, keyCode, event ->
if (keyCode == KeyEvent.KEYCODE_BUTTON_B && event.action == KeyEvent.ACTION_DOWN) {
dialog?.onBackPressed()
true
} else {
false
}
}
}
/**
@ -59,6 +67,13 @@ class AppDialog(val item: AppItem? = null) : BottomSheetDialogFragment() {
game_title.text = item.title
game_subtitle.text = item.subTitle ?: getString(R.string.metadata_missing)
game_play.setOnClickListener {
val intent = Intent(activity, EmulationActivity::class.java)
intent.data = item.uri
startActivity(intent)
}
val shortcutManager = activity?.getSystemService(ShortcutManager::class.java)!!
game_pin.isEnabled = shortcutManager.isRequestPinShortcutSupported
@ -76,13 +91,6 @@ class AppDialog(val item: AppItem? = null) : BottomSheetDialogFragment() {
shortcutManager.requestPinShortcut(info.build(), null)
}
game_play.setOnClickListener {
val intent = Intent(activity, EmulationActivity::class.java)
intent.data = item.uri
startActivity(intent)
}
} else
activity?.supportFragmentManager?.beginTransaction()?.remove(this)?.commit()
}

View File

@ -13,7 +13,7 @@ import android.os.ParcelFileDescriptor
import android.util.Log
import android.view.Surface
import android.view.SurfaceHolder
import android.view.WindowManager
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.preference.PreferenceManager
import emu.skyline.loader.getRomFormat
@ -121,7 +121,12 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback {
setContentView(R.layout.emu_activity)
window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN)
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_IMMERSIVE
or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_FULLSCREEN)
val preference = File("${applicationInfo.dataDir}/shared_prefs/${applicationInfo.packageName}_preferences.xml")
preferenceFd = ParcelFileDescriptor.open(preference, ParcelFileDescriptor.MODE_READ_WRITE)

View File

@ -7,6 +7,7 @@ package emu.skyline
import android.content.Intent
import android.content.SharedPreferences
import android.content.pm.ActivityInfo
import android.net.Uri
import android.os.Bundle
import android.util.Log
@ -29,7 +30,6 @@ import emu.skyline.adapter.GridLayoutSpan
import emu.skyline.adapter.LayoutType
import emu.skyline.loader.BaseLoader
import emu.skyline.loader.NroLoader
import emu.skyline.utility.AppDialog
import emu.skyline.utility.RandomAccessDocument
import kotlinx.android.synthetic.main.main_activity.*
import kotlinx.android.synthetic.main.titlebar.*
@ -101,7 +101,10 @@ class MainActivity : AppCompatActivity(), View.OnClickListener, View.OnLongClick
thread(start = true) {
val snackbar = Snackbar.make(findViewById(android.R.id.content), getString(R.string.searching_roms), Snackbar.LENGTH_INDEFINITE)
runOnUiThread { snackbar.show() }
runOnUiThread {
snackbar.show()
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LOCKED
}
try {
runOnUiThread { adapter.clear() }
@ -134,7 +137,10 @@ class MainActivity : AppCompatActivity(), View.OnClickListener, View.OnLongClick
}
}
runOnUiThread { snackbar.dismiss() }
runOnUiThread {
snackbar.dismiss()
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
}
}
}
@ -184,6 +190,23 @@ class MainActivity : AppCompatActivity(), View.OnClickListener, View.OnLongClick
}
}
app_list.addOnScrollListener(object : RecyclerView.OnScrollListener() {
var y : Int = 0
override fun onScrolled(recyclerView : RecyclerView, dx : Int, dy : Int) {
y += dy
if (!app_list.isInTouchMode) {
if (y == 0)
toolbar_layout.setExpanded(true)
else
toolbar_layout.setExpanded(false)
}
super.onScrolled(recyclerView, dx, dy)
}
})
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

View File

@ -155,6 +155,8 @@ internal class AppAdapter(val context: Context?, private val layoutType: LayoutT
if (context is View.OnLongClickListener)
holder.card!!.setOnLongClickListener(context as View.OnLongClickListener)
holder.title.isSelected = true
}
} else if (viewType == Header.ordinal) {
val view = inflater.inflate(R.layout.section_item, parent, false)

View File

@ -4,6 +4,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:nextFocusRight="@id/game_play"
android:padding="16dp">
<com.google.android.material.imageview.ShapeableImageView
@ -11,6 +12,7 @@
android:layout_width="150dp"
android:layout_height="150dp"
android:contentDescription="@string/icon"
android:focusable="false"
app:shapeAppearanceOverlay="@style/roundedAppImage" />
<LinearLayout
@ -47,6 +49,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="6dp"
android:focusedByDefault="true"
android:text="@string/play"
app:icon="@drawable/ic_play" />

View File

@ -16,38 +16,46 @@
card_view:cardCornerRadius="4dp">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_width="155dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/icon"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_width="match_parent"
android:layout_height="155dp"
android:layout_alignParentTop="false"
android:layout_centerHorizontal="true"
android:contentDescription="@string/icon" />
android:contentDescription="@string/icon"
android:scaleType="centerCrop" />
<TextView
android:id="@+id/text_title"
android:layout_width="150dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/icon"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:paddingStart="15dp"
android:paddingTop="15dp"
android:paddingTop="10dp"
android:paddingEnd="15dp"
android:singleLine="true"
android:textAlignment="center"
android:textAppearance="?android:attr/textAppearanceListItem"
tools:ignore="RelativeOverlap" />
<TextView
android:id="@+id/text_subtitle"
android:layout_width="150dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/text_title"
android:layout_alignStart="@id/text_title"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:marqueeRepeatLimit="marquee_forever"
android:paddingBottom="15dp"
android:singleLine="true"
android:textAlignment="center"
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
android:textColor="@android:color/tertiary_text_light" />

View File

@ -3,6 +3,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true"
tools:context=".EmulationActivity">
<SurfaceView

View File

@ -28,7 +28,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:padding="8dp"
app:maxImageSize="26dp"
app:srcCompat="@drawable/ic_open" />
@ -37,7 +36,6 @@
style="@style/Widget.MaterialComponents.FloatingActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp"
app:maxImageSize="26dp"
app:srcCompat="@drawable/ic_log" />
</LinearLayout>

View File

@ -1,8 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.appbar.AppBarLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:descendantFocusability="afterDescendants"
app:liftOnScroll="true">
<com.google.android.material.appbar.MaterialToolbar