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 <Jays2Kings@users.noreply.github.com>
This commit is contained in:
arkon 2021-04-16 22:39:19 -04:00
parent a59e134862
commit 3287ca9cf2
8 changed files with 64 additions and 16 deletions

View File

@ -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.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import android.view.Gravity import android.view.Gravity
@ -7,15 +8,21 @@ import android.view.LayoutInflater
import android.view.MenuItem import android.view.MenuItem
import android.widget.FrameLayout import android.widget.FrameLayout
import androidx.annotation.ArrayRes import androidx.annotation.ArrayRes
import androidx.appcompat.view.menu.MenuBuilder
import androidx.appcompat.widget.PopupMenu 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 com.tfcporciuncula.flow.Preference
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.databinding.SpinnerPreferenceBinding 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) { FrameLayout(context, attrs) {
private var entries = emptyList<String>() private var entries = emptyList<String>()
private var selectedPosition = 0
private var popup: PopupMenu? = null private var popup: PopupMenu? = null
var onItemSelectedListener: ((Int) -> Unit)? = 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) private val binding = SpinnerPreferenceBinding.inflate(LayoutInflater.from(context), this, false)
init { init {
addView(binding.root) 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 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 this.entries = entries
binding.details.text = entries.firstOrNull().orEmpty() binding.details.text = entries.firstOrNull().orEmpty()
@ -48,6 +64,14 @@ class SpinnerPreference @JvmOverloads constructor(context: Context, attrs: Attri
} }
fun setSelection(selection: Int) { 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() binding.details.text = entries.getOrNull(selection).orEmpty()
} }
@ -118,11 +142,19 @@ class SpinnerPreference @JvmOverloads constructor(context: Context, attrs: Attri
return pos return pos
} }
@SuppressLint("RestrictedApi")
fun createPopupMenu(onItemClick: (Int) -> Unit): PopupMenu { fun createPopupMenu(onItemClick: (Int) -> Unit): PopupMenu {
val popup = PopupMenu(context, this, Gravity.END, R.attr.actionOverflowMenuStyle, 0) val popup = PopupMenu(context, this, Gravity.END, R.attr.actionOverflowMenuStyle, 0)
entries.forEachIndexed { index, entry -> entries.forEachIndexed { index, entry ->
popup.menu.add(0, index, 0, 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 -> popup.setOnMenuItemClickListener { menuItem ->
val pos = menuClicked(menuItem) val pos = menuClicked(menuItem)
onItemClick(pos) onItemClick(pos)

View File

@ -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>

View File

@ -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>

View File

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

View File

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

View File

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

View File

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

View File

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