Jelajahi Sumber

Add checkmark beside selected popup menu item

Based on what's in J2K. Also renamed to MaterialSpinnerView to match what's there.

Co-authored-by: Jays2Kings <[email protected]>
arkon 4 tahun lalu
induk
melakukan
3287ca9cf2

+ 37 - 5
app/src/main/java/eu/kanade/tachiyomi/ui/reader/setting/SpinnerPreference.kt → app/src/main/java/eu/kanade/tachiyomi/widget/MaterialSpinnerView.kt

@@ -1,5 +1,6 @@
-package eu.kanade.tachiyomi.ui.reader.setting
+package eu.kanade.tachiyomi.widget
 
+import android.annotation.SuppressLint
 import android.content.Context
 import android.util.AttributeSet
 import android.view.Gravity
@@ -7,15 +8,21 @@ import android.view.LayoutInflater
 import android.view.MenuItem
 import android.widget.FrameLayout
 import androidx.annotation.ArrayRes
+import androidx.appcompat.view.menu.MenuBuilder
 import androidx.appcompat.widget.PopupMenu
+import androidx.core.content.ContextCompat
+import androidx.core.view.forEach
+import androidx.core.view.get
 import com.tfcporciuncula.flow.Preference
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.databinding.SpinnerPreferenceBinding
+import eu.kanade.tachiyomi.util.system.getResourceColor
 
-class SpinnerPreference @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
+class MaterialSpinnerView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
     FrameLayout(context, attrs) {
 
     private var entries = emptyList<String>()
+    private var selectedPosition = 0
     private var popup: PopupMenu? = null
 
     var onItemSelectedListener: ((Int) -> Unit)? = null
@@ -30,17 +37,26 @@ class SpinnerPreference @JvmOverloads constructor(context: Context, attrs: Attri
             }
         }
 
+    private val emptyIcon by lazy {
+        ContextCompat.getDrawable(context, R.drawable.ic_blank_24dp)
+    }
+    private val checkmarkIcon by lazy {
+        ContextCompat.getDrawable(context, R.drawable.ic_check_24dp)?.mutate()?.apply {
+            setTint(context.getResourceColor(android.R.attr.textColorPrimary))
+        }
+    }
+
     private val binding = SpinnerPreferenceBinding.inflate(LayoutInflater.from(context), this, false)
 
     init {
         addView(binding.root)
 
-        val attr = context.obtainStyledAttributes(attrs, R.styleable.SpinnerPreference)
+        val attr = context.obtainStyledAttributes(attrs, R.styleable.MaterialSpinnerView)
 
-        val title = attr.getString(R.styleable.SpinnerPreference_title).orEmpty()
+        val title = attr.getString(R.styleable.MaterialSpinnerView_title).orEmpty()
         binding.title.text = title
 
-        val entries = (attr.getTextArray(R.styleable.SpinnerPreference_android_entries) ?: emptyArray()).map { it.toString() }
+        val entries = (attr.getTextArray(R.styleable.MaterialSpinnerView_android_entries) ?: emptyArray()).map { it.toString() }
         this.entries = entries
         binding.details.text = entries.firstOrNull().orEmpty()
 
@@ -48,6 +64,14 @@ class SpinnerPreference @JvmOverloads constructor(context: Context, attrs: Attri
     }
 
     fun setSelection(selection: Int) {
+        popup?.menu?.get(selectedPosition)?.let {
+            it.icon = emptyIcon
+            it.title = entries[selectedPosition]
+        }
+        selectedPosition = selection
+        popup?.menu?.get(selectedPosition)?.let {
+            it.icon = checkmarkIcon
+        }
         binding.details.text = entries.getOrNull(selection).orEmpty()
     }
 
@@ -118,11 +142,19 @@ class SpinnerPreference @JvmOverloads constructor(context: Context, attrs: Attri
         return pos
     }
 
+    @SuppressLint("RestrictedApi")
     fun createPopupMenu(onItemClick: (Int) -> Unit): PopupMenu {
         val popup = PopupMenu(context, this, Gravity.END, R.attr.actionOverflowMenuStyle, 0)
         entries.forEachIndexed { index, entry ->
             popup.menu.add(0, index, 0, entry)
         }
+        (popup.menu as? MenuBuilder)?.setOptionalIconsVisible(true)
+        popup.menu.forEach {
+            it.icon = emptyIcon
+        }
+        popup.menu.getItem(selectedPosition)?.let {
+            it.icon = checkmarkIcon
+        }
         popup.setOnMenuItemClickListener { menuItem ->
             val pos = menuClicked(menuItem)
             onItemClick(pos)

+ 7 - 0
app/src/main/res/drawable/ic_blank_24dp.xml

@@ -0,0 +1,7 @@
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <size
+        android:width="24dp"
+        android:height="24dp" />
+    <solid android:color="@android:color/transparent" />
+</shape>

+ 9 - 0
app/src/main/res/drawable/ic_check_24dp.xml

@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24.0"
+    android:viewportHeight="24.0">
+    <path
+        android:fillColor="@android:color/black"
+        android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z" />
+</vector>

+ 2 - 2
app/src/main/res/layout/reader_general_settings.xml

@@ -10,14 +10,14 @@
         android:layout_height="wrap_content"
         android:orientation="vertical">
 
-        <eu.kanade.tachiyomi.ui.reader.setting.SpinnerPreference
+        <eu.kanade.tachiyomi.widget.MaterialSpinnerView
             android:id="@+id/rotation_mode"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:entries="@array/rotation_type"
             app:title="@string/pref_rotation_type" />
 
-        <eu.kanade.tachiyomi.ui.reader.setting.SpinnerPreference
+        <eu.kanade.tachiyomi.widget.MaterialSpinnerView
             android:id="@+id/background_color"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"

+ 4 - 4
app/src/main/res/layout/reader_pager_settings.xml

@@ -15,28 +15,28 @@
         android:paddingEnd="16dp"
         android:textAppearance="@style/TextAppearance.Medium.SubHeading" />
 
-    <eu.kanade.tachiyomi.ui.reader.setting.SpinnerPreference
+    <eu.kanade.tachiyomi.widget.MaterialSpinnerView
         android:id="@+id/pager_nav"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:entries="@array/pager_nav"
         app:title="@string/pref_viewer_nav" />
 
-    <eu.kanade.tachiyomi.ui.reader.setting.SpinnerPreference
+    <eu.kanade.tachiyomi.widget.MaterialSpinnerView
         android:id="@+id/tapping_inverted"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:entries="@array/invert_tapping_mode"
         app:title="@string/pref_read_with_tapping_inverted" />
 
-    <eu.kanade.tachiyomi.ui.reader.setting.SpinnerPreference
+    <eu.kanade.tachiyomi.widget.MaterialSpinnerView
         android:id="@+id/scale_type"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:entries="@array/image_scale_type"
         app:title="@string/pref_image_scale_type" />
 
-    <eu.kanade.tachiyomi.ui.reader.setting.SpinnerPreference
+    <eu.kanade.tachiyomi.widget.MaterialSpinnerView
         android:id="@+id/zoom_start"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"

+ 1 - 1
app/src/main/res/layout/reader_reading_mode_settings.xml

@@ -10,7 +10,7 @@
         android:layout_height="wrap_content"
         android:orientation="vertical">
 
-        <eu.kanade.tachiyomi.ui.reader.setting.SpinnerPreference
+        <eu.kanade.tachiyomi.widget.MaterialSpinnerView
             android:id="@+id/viewer"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"

+ 3 - 3
app/src/main/res/layout/reader_webtoon_settings.xml

@@ -15,21 +15,21 @@
         android:paddingEnd="16dp"
         android:textAppearance="@style/TextAppearance.Medium.SubHeading" />
 
-    <eu.kanade.tachiyomi.ui.reader.setting.SpinnerPreference
+    <eu.kanade.tachiyomi.widget.MaterialSpinnerView
         android:id="@+id/webtoon_nav"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:entries="@array/webtoon_nav"
         app:title="@string/pref_viewer_nav" />
 
-    <eu.kanade.tachiyomi.ui.reader.setting.SpinnerPreference
+    <eu.kanade.tachiyomi.widget.MaterialSpinnerView
         android:id="@+id/tapping_inverted"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:entries="@array/invert_tapping_mode"
         app:title="@string/pref_read_with_tapping_inverted" />
 
-    <eu.kanade.tachiyomi.ui.reader.setting.SpinnerPreference
+    <eu.kanade.tachiyomi.widget.MaterialSpinnerView
         android:id="@+id/webtoon_side_padding"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"

+ 1 - 1
app/src/main/res/values/attrs.xml

@@ -11,7 +11,7 @@
         <attr name="max_seek" format="integer"/>
     </declare-styleable>
 
-    <declare-styleable name="SpinnerPreference">
+    <declare-styleable name="MaterialSpinnerView">
         <attr name="title" format="reference|string"/>
         <attr name="android:entries"/>
         <attr name="summary" format="reference|string" />