chore(custom-color): refactor EditText and TextInputLayout color handling (#885)

This commit is contained in:
Cuong-Tran 2025-04-30 02:49:27 +07:00
parent 29cf391ede
commit e40abcf40b
6 changed files with 92 additions and 142 deletions

View file

@ -1,8 +1,6 @@
package eu.kanade.presentation.more.settings.screen package eu.kanade.presentation.more.settings.screen
import android.content.Context import android.content.Context
import android.content.res.ColorStateList
import android.os.Build
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
@ -258,25 +256,11 @@ object SettingsTrackingScreen : SearchableSettings {
val usernameEditText = binding.usernameEditText val usernameEditText = binding.usernameEditText
val passwordEditText = binding.passwordEditText val passwordEditText = binding.passwordEditText
// Apply color scheme and selection handles listOf(
listOf(usernameEditText, passwordEditText).forEach { editText -> usernameEditText,
editText.setTextColor(colorScheme.textColor) passwordEditText,
editText.highlightColor = colorScheme.textHighlightColor ).forEach {
colorScheme.setEditTextColor(it)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
editText.textSelectHandle?.let { drawable ->
drawable.setTint(colorScheme.primary)
editText.setTextSelectHandle(drawable)
}
editText.textSelectHandleLeft?.let { drawable ->
drawable.setTint(colorScheme.primary)
editText.setTextSelectHandleLeft(drawable)
}
editText.textSelectHandleRight?.let { drawable ->
drawable.setTint(colorScheme.primary)
editText.setTextSelectHandleRight(drawable)
}
}
} }
usernameInputLayout.hint = usernameHint usernameInputLayout.hint = usernameHint
@ -306,43 +290,11 @@ object SettingsTrackingScreen : SearchableSettings {
val usernameInputLayout = binding.usernameInputLayout val usernameInputLayout = binding.usernameInputLayout
val passwordInputLayout = binding.passwordInputLayout val passwordInputLayout = binding.passwordInputLayout
val (strokeColorFocused, strokeColorDefault, hintColor, cursorColor) = if (inputError) { listOf(
arrayOf( usernameInputLayout,
colorScheme.error, passwordInputLayout,
colorScheme.error, ).forEach {
colorScheme.error, colorScheme.setTextInputLayoutColor(it, inputError)
colorScheme.error,
)
} else {
arrayOf(
colorScheme.primary,
colorScheme.onSurfaceVariant,
colorScheme.primary,
colorScheme.primary,
)
}
val boxStrokeColorStateList = ColorStateList(
arrayOf(
intArrayOf(android.R.attr.state_focused),
intArrayOf(), // Default state
),
intArrayOf(
strokeColorFocused,
strokeColorDefault,
),
)
val hintTextColorStateList = ColorStateList.valueOf(hintColor)
val endIconTintList = ColorStateList.valueOf(colorScheme.onSurfaceVariant)
val cursorColorStateList = ColorStateList.valueOf(cursorColor)
listOf(usernameInputLayout, passwordInputLayout).forEach {
it.setBoxStrokeColorStateList(boxStrokeColorStateList)
it.hintTextColor = hintTextColorStateList
it.setEndIconTintList(endIconTintList)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
it.cursorColor = cursorColorStateList
}
} }
}, },
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),

View file

@ -4,6 +4,7 @@ import android.app.UiModeManager
import android.content.Context import android.content.Context
import android.content.res.ColorStateList import android.content.res.ColorStateList
import android.os.Build import android.os.Build
import android.widget.EditText
import androidx.annotation.ColorInt import androidx.annotation.ColorInt
import androidx.compose.material3.ColorScheme import androidx.compose.material3.ColorScheme
import androidx.compose.material3.surfaceColorAtElevation import androidx.compose.material3.surfaceColorAtElevation
@ -11,7 +12,10 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.core.content.getSystemService import androidx.core.content.getSystemService
import androidx.core.graphics.drawable.toDrawable
import com.google.android.material.progressindicator.LinearProgressIndicator import com.google.android.material.progressindicator.LinearProgressIndicator
import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout
import com.materialkolor.Contrast import com.materialkolor.Contrast
import com.materialkolor.PaletteStyle import com.materialkolor.PaletteStyle
import com.materialkolor.dynamicColorScheme import com.materialkolor.dynamicColorScheme
@ -188,7 +192,7 @@ class AndroidViewColorScheme(
), ),
intArrayOf( intArrayOf(
onPrimary, onPrimary,
onSurface, onSurfaceVariant,
), ),
) )
@ -199,7 +203,7 @@ class AndroidViewColorScheme(
), ),
intArrayOf( intArrayOf(
primary, primary,
onSurface, onSurfaceVariant,
), ),
) )
@ -210,7 +214,7 @@ class AndroidViewColorScheme(
), ),
intArrayOf( intArrayOf(
primary, primary,
onSurface, onSurfaceVariant,
), ),
) )
@ -227,6 +231,66 @@ class AndroidViewColorScheme(
), ),
) )
/**
* Set the color of the [TextInputEditText] or [EditText].
* @param editText The EditText to set the color for.
*/
fun setEditTextColor(
editText: EditText,
) {
editText.setTextColor(onSurfaceVariant)
editText.highlightColor = inversePrimary
editText.backgroundTintList = editTextBackgroundTintList
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
editText.textCursorDrawable = primary.toDrawable()
editText.textSelectHandle?.let { drawable ->
drawable.setTint(primary)
editText.setTextSelectHandle(drawable)
}
editText.textSelectHandleLeft?.let { drawable ->
drawable.setTint(primary)
editText.setTextSelectHandleLeft(drawable)
}
editText.textSelectHandleRight?.let { drawable ->
drawable.setTint(primary)
editText.setTextSelectHandleRight(drawable)
}
}
}
fun setTextInputLayoutColor(
inputLayout: TextInputLayout,
isError: Boolean = false,
) {
val (strokeColorFocused, strokeColorDefault, hintColor, cursorColor) = if (isError) {
arrayOf(error, error, error, error)
} else {
arrayOf(primary, onSurfaceVariant, primary, primary)
}
val boxStrokeColorStateList = ColorStateList(
arrayOf(
intArrayOf(android.R.attr.state_focused),
intArrayOf(), // Default state
),
intArrayOf(
strokeColorFocused,
strokeColorDefault,
),
)
val hintTextColorStateList = ColorStateList.valueOf(hintColor)
val endIconTintList = ColorStateList.valueOf(onSurfaceVariant)
val cursorColorStateList = ColorStateList.valueOf(cursorColor)
inputLayout.setBoxStrokeColorStateList(boxStrokeColorStateList)
inputLayout.hintTextColor = hintTextColorStateList
inputLayout.setEndIconTintList(endIconTintList)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
inputLayout.cursorColor = cursorColorStateList
}
}
companion object { companion object {
fun LinearProgressIndicator.setColors(colorScheme: AndroidViewColorScheme) { fun LinearProgressIndicator.setColors(colorScheme: AndroidViewColorScheme) {
trackColor = colorScheme.secondaryContainer trackColor = colorScheme.secondaryContainer

View file

@ -1,6 +1,5 @@
package eu.kanade.tachiyomi.ui.browse.migration.advanced.design package eu.kanade.tachiyomi.ui.browse.migration.advanced.design
import android.os.Build
import android.view.LayoutInflater import android.view.LayoutInflater
import android.widget.CompoundButton import android.widget.CompoundButton
import android.widget.RadioButton import android.widget.RadioButton
@ -14,7 +13,6 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.graphics.drawable.toDrawable
import androidx.core.view.isVisible import androidx.core.view.isVisible
import eu.kanade.presentation.components.AdaptiveSheet import eu.kanade.presentation.components.AdaptiveSheet
import eu.kanade.presentation.theme.colorscheme.AndroidViewColorScheme import eu.kanade.presentation.theme.colorscheme.AndroidViewColorScheme
@ -83,26 +81,7 @@ fun MigrationBottomSheetDialog(
binding.HideNotFoundManga.thumbTintList = colorScheme.thumbTintList binding.HideNotFoundManga.thumbTintList = colorScheme.thumbTintList
binding.OnlyShowUpdates.thumbTintList = colorScheme.thumbTintList binding.OnlyShowUpdates.thumbTintList = colorScheme.thumbTintList
with(binding.extraSearchParamText) { colorScheme.setEditTextColor(binding.extraSearchParamText)
highlightColor = colorScheme.textHighlightColor
backgroundTintList = colorScheme.editTextBackgroundTintList
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
textCursorDrawable = colorScheme.primary.toDrawable()
textSelectHandle?.let { drawable ->
drawable.setTint(colorScheme.primary)
setTextSelectHandle(drawable)
}
textSelectHandleLeft?.let { drawable ->
drawable.setTint(colorScheme.primary)
setTextSelectHandleLeft(drawable)
}
textSelectHandleRight?.let { drawable ->
drawable.setTint(colorScheme.primary)
setTextSelectHandleRight(drawable)
}
}
}
// KMK <-- // KMK <--
binding.root binding.root
}, },

View file

@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.ui.manga
import android.content.Context import android.content.Context
import android.content.res.ColorStateList import android.content.res.ColorStateList
import android.graphics.Color import android.graphics.Color
import android.os.Build
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.widget.AdapterView import android.widget.AdapterView
@ -359,23 +358,7 @@ private fun onViewCreated(
binding.thumbnailUrl, binding.thumbnailUrl,
binding.mangaDescription, binding.mangaDescription,
).forEach { ).forEach {
it.setTextColor(colorScheme.textColor) colorScheme.setEditTextColor(it)
it.highlightColor = colorScheme.textHighlightColor
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
it.textSelectHandle?.let { drawable ->
drawable.setTint(colorScheme.iconColor)
it.setTextSelectHandle(drawable)
}
it.textSelectHandleLeft?.let { drawable ->
drawable.setTint(colorScheme.iconColor)
it.setTextSelectHandleLeft(drawable)
}
it.textSelectHandleRight?.let { drawable ->
drawable.setTint(colorScheme.iconColor)
it.setTextSelectHandleRight(drawable)
}
}
} }
listOf( listOf(
binding.titleOutline, binding.titleOutline,
@ -384,11 +367,7 @@ private fun onViewCreated(
binding.thumbnailUrlOutline, binding.thumbnailUrlOutline,
binding.mangaDescriptionOutline, binding.mangaDescriptionOutline,
).forEach { ).forEach {
it.boxStrokeColor = colorScheme.iconColor colorScheme.setTextInputLayoutColor(it)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
it.cursorColor = ColorStateList.valueOf(colorScheme.iconColor)
}
} }
binding.autofillFromTracker.setTextColor(colorScheme.btnTextColor) binding.autofillFromTracker.setTextColor(colorScheme.btnTextColor)

View file

@ -1,14 +1,12 @@
package eu.kanade.tachiyomi.widget.materialdialogs package eu.kanade.tachiyomi.widget.materialdialogs
import android.content.Context import android.content.Context
import android.content.res.ColorStateList
import android.graphics.Canvas import android.graphics.Canvas
import android.graphics.ColorFilter import android.graphics.ColorFilter
import android.graphics.Paint import android.graphics.Paint
import android.graphics.PixelFormat import android.graphics.PixelFormat
import android.graphics.RectF import android.graphics.RectF
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.os.Build
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodManager
import android.widget.TextView import android.widget.TextView
@ -39,7 +37,7 @@ fun DialogStubTextinputBinding.setPositiveButton(text: String, onClick: (String)
positiveButton.text = text positiveButton.text = text
positiveButton.setOnClickListener { positiveButton.setOnClickListener {
val textEdit = textField.editText val textEdit = textInputLayout.editText
onClick(textEdit?.text?.toString() ?: "") onClick(textEdit?.text?.toString() ?: "")
} }
return this return this
@ -56,13 +54,13 @@ fun DialogStubTextinputBinding.setNegativeButton(text: String, onClick: () -> Un
@Suppress("unused") @Suppress("unused")
fun DialogStubTextinputBinding.setHint(hint: String? = null): DialogStubTextinputBinding { fun DialogStubTextinputBinding.setHint(hint: String? = null): DialogStubTextinputBinding {
textField.hint = hint textInputLayout.hint = hint
return this return this
} }
fun DialogStubTextinputBinding.setTextEdit(prefill: String? = null): DialogStubTextinputBinding { fun DialogStubTextinputBinding.setTextEdit(prefill: String? = null): DialogStubTextinputBinding {
// KMK <-- // KMK <--
textField.editText?.apply { textInputLayout.editText?.apply {
setText(prefill, TextView.BufferType.EDITABLE) setText(prefill, TextView.BufferType.EDITABLE)
post { post {
requestFocusFromTouch() requestFocusFromTouch()
@ -73,38 +71,15 @@ fun DialogStubTextinputBinding.setTextEdit(prefill: String? = null): DialogStubT
return this return this
} }
fun DialogStubTextinputBinding.setColors(colors: AndroidViewColorScheme): DialogStubTextinputBinding { fun DialogStubTextinputBinding.setColors(colorScheme: AndroidViewColorScheme): DialogStubTextinputBinding {
textField.boxStrokeColor = colors.iconColor colorScheme.setTextInputLayoutColor(textInputLayout)
colorScheme.setEditTextColor(textInputEdit)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { alertTitle.setTextColor(colorScheme.textColor)
textField.cursorColor = ColorStateList.valueOf(colors.iconColor) positiveButton.setTextColor(colorScheme.iconColor)
} negativeButton.setTextColor(colorScheme.iconColor)
textField.editText?.apply { root.background = RoundedCornerDrawable(color = colorScheme.dialogBgColor)
setTextColor(colors.textColor)
highlightColor = colors.textHighlightColor
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
textSelectHandle?.let { drawable ->
drawable.setTint(colors.iconColor)
setTextSelectHandle(drawable)
}
textSelectHandleLeft?.let { drawable ->
drawable.setTint(colors.iconColor)
setTextSelectHandleLeft(drawable)
}
textSelectHandleRight?.let { drawable ->
drawable.setTint(colors.iconColor)
setTextSelectHandleRight(drawable)
}
}
}
alertTitle.setTextColor(colors.textColor)
positiveButton.setTextColor(colors.iconColor)
negativeButton.setTextColor(colors.iconColor)
root.background = RoundedCornerDrawable(color = colors.dialogBgColor)
return this return this
} }

View file

@ -15,12 +15,13 @@
android:layout_marginBottom="16dp" /> android:layout_marginBottom="16dp" />
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/text_field" android:id="@+id/text_input_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="16dp"> android:layout_marginBottom="16dp">
<eu.kanade.tachiyomi.widget.TachiyomiTextInputEditText <eu.kanade.tachiyomi.widget.TachiyomiTextInputEditText
android:id="@+id/text_input_edit"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />