Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: custom theme color in various AndroidView #656

Merged
merged 8 commits into from
Jan 25, 2025
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package eu.kanade.presentation.components

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.TextView
import androidx.annotation.LayoutRes
import eu.kanade.presentation.theme.colorscheme.AndroidViewColorScheme

// KMK -->
internal class SpinnerAdapter(
context: Context,
@LayoutRes val resource: Int,
objects: List<String>,
val colorScheme: AndroidViewColorScheme,
) : ArrayAdapter<String>(context, resource, objects) {
private val mInflater = LayoutInflater.from(context)

override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
return createViewFromResource(mInflater, position, convertView, parent, resource)
}

override fun getDropDownView(position: Int, convertView: View?, parent: ViewGroup): View {
return createViewFromResource(mInflater, position, convertView, parent, resource)
}

private fun createViewFromResource(
inflater: LayoutInflater,
position: Int,
convertView: View?,
parent: ViewGroup,
resource: Int,
): View {
val text: TextView

val view = convertView ?: inflater.inflate(resource, parent, false)

try {
// If no custom field is assigned, assume the whole resource is a TextView
text = view as TextView
} catch (e: ClassCastException) {
throw IllegalStateException("ArrayAdapter requires the resource ID to be a TextView", e)
}

val item: String? = getItem(position)
if (item != null) text.text = item

text.setTextColor(colorScheme.textColor)
text.setBackgroundColor(colorScheme.dropdownBgColor)

return view
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,16 @@ package eu.kanade.presentation.theme.colorscheme

import android.app.UiModeManager
import android.content.Context
import android.content.res.ColorStateList
import android.os.Build
import androidx.annotation.ColorInt
import androidx.compose.material3.ColorScheme
import androidx.compose.material3.surfaceColorAtElevation
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.unit.dp
import androidx.core.content.getSystemService
import com.google.android.material.progressindicator.LinearProgressIndicator
import com.materialkolor.Contrast
import com.materialkolor.PaletteStyle
import com.materialkolor.dynamicColorScheme
Expand Down Expand Up @@ -51,3 +58,179 @@ private class CustomCompatColorScheme(
},
)
}

class AndroidViewColorScheme(
colorScheme: ColorScheme,
) {
@ColorInt val primary: Int = colorScheme.primary.toArgb()

@ColorInt val onPrimary: Int = colorScheme.onPrimary.toArgb()

@ColorInt val primaryContainer: Int = colorScheme.primaryContainer.toArgb()

@ColorInt val onPrimaryContainer: Int = colorScheme.onPrimaryContainer.toArgb()

@ColorInt val inversePrimary: Int = colorScheme.inversePrimary.toArgb()

@ColorInt val secondary: Int = colorScheme.secondary.toArgb()

@ColorInt val onSecondary: Int = colorScheme.onSecondary.toArgb()

@ColorInt val secondaryContainer: Int = colorScheme.secondaryContainer.toArgb()

@ColorInt val onSecondaryContainer: Int = colorScheme.onSecondaryContainer.toArgb()

@ColorInt val tertiary: Int = colorScheme.tertiary.toArgb()

@ColorInt val onTertiary: Int = colorScheme.onTertiary.toArgb()

@ColorInt val tertiaryContainer: Int = colorScheme.tertiaryContainer.toArgb()

@ColorInt val onTertiaryContainer: Int = colorScheme.onTertiaryContainer.toArgb()

@ColorInt val background: Int = colorScheme.background.toArgb()

@ColorInt val onBackground: Int = colorScheme.onBackground.toArgb()

@ColorInt val surface: Int = colorScheme.surface.toArgb()

@ColorInt val onSurface: Int = colorScheme.onSurface.toArgb()

@ColorInt val surfaceVariant: Int = colorScheme.surfaceVariant.toArgb()

@ColorInt val onSurfaceVariant: Int = colorScheme.onSurfaceVariant.toArgb()

@ColorInt val surfaceTint: Int = colorScheme.surfaceTint.toArgb()

@ColorInt val inverseSurface: Int = colorScheme.inverseSurface.toArgb()

@ColorInt val inverseOnSurface: Int = colorScheme.inverseOnSurface.toArgb()

@ColorInt val error: Int = colorScheme.error.toArgb()

@ColorInt val onError: Int = colorScheme.onError.toArgb()

@ColorInt val errorContainer: Int = colorScheme.errorContainer.toArgb()

@ColorInt val onErrorContainer: Int = colorScheme.onErrorContainer.toArgb()

@ColorInt val outline: Int = colorScheme.outline.toArgb()

@ColorInt val outlineVariant: Int = colorScheme.outlineVariant.toArgb()

@ColorInt val scrim: Int = colorScheme.scrim.toArgb()

@ColorInt val surfaceBright: Int = colorScheme.surfaceBright.toArgb()

@ColorInt val surfaceDim: Int = colorScheme.surfaceDim.toArgb()

@ColorInt val surfaceContainer: Int = colorScheme.surfaceContainer.toArgb()

@ColorInt val surfaceContainerHigh: Int = colorScheme.surfaceContainerHigh.toArgb()

@ColorInt val surfaceContainerHighest: Int = colorScheme.surfaceContainerHighest.toArgb()

@ColorInt val surfaceContainerLow: Int = colorScheme.surfaceContainerLow.toArgb()

@ColorInt val surfaceContainerLowest: Int = colorScheme.surfaceContainerLowest.toArgb()

@ColorInt
val textColor: Int = onSurfaceVariant

@ColorInt
val textHighlightColor: Int = inversePrimary

@ColorInt
val iconColor: Int = primary

@ColorInt
val tagColor: Int = outlineVariant

@ColorInt
val tagTextColor: Int = onSurfaceVariant

@ColorInt
val btnTextColor: Int = onPrimary

@ColorInt
val btnBgColor: Int = surfaceTint

@ColorInt
val dropdownBgColor: Int = surfaceContainerHighest

@ColorInt
val dialogBgColor: Int = surfaceContainerHigh

@ColorInt
val surfaceElevation = colorScheme.surfaceColorAtElevation(4.dp).toArgb()

@ColorInt
val ratingBarColor = primary

@ColorInt
val ratingBarSecondaryColor = outlineVariant

/* MaterialSwitch */
val trackTintList = ColorStateList(
arrayOf(
intArrayOf(android.R.attr.state_checked),
intArrayOf(-android.R.attr.state_checked),
),
intArrayOf(
primary,
surface,
),
)
val thumbTintList = ColorStateList(
arrayOf(
intArrayOf(android.R.attr.state_checked),
intArrayOf(-android.R.attr.state_checked),
),
intArrayOf(
onPrimary,
onSurface,
),
)

val checkboxTintList = ColorStateList(
arrayOf(
intArrayOf(android.R.attr.state_checked),
intArrayOf(-android.R.attr.state_checked),
),
intArrayOf(
primary,
onSurface,
),
)

val editTextBackgroundTintList = ColorStateList(
arrayOf(
intArrayOf(android.R.attr.state_focused),
intArrayOf(-android.R.attr.state_focused),
),
intArrayOf(
primary,
onSurface,
),
)

val imageButtonTintList = ColorStateList(
arrayOf(
intArrayOf(android.R.attr.state_pressed), // Pressed state
intArrayOf(android.R.attr.state_focused), // Focused state
intArrayOf(), // Default state
),
intArrayOf(
primary, // Pressed color
primary, // Focused color
primary, // Default color
),
)

companion object {
fun LinearProgressIndicator.setColors(colorScheme: AndroidViewColorScheme) {
trackColor = colorScheme.secondaryContainer
setIndicatorColor(colorScheme.primary)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package eu.kanade.tachiyomi.ui.browse.migration.advanced.design

import android.content.res.ColorStateList
import android.graphics.drawable.ColorDrawable
import android.os.Build
import android.view.LayoutInflater
Expand All @@ -15,10 +14,10 @@ import androidx.compose.runtime.State
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.view.isVisible
import eu.kanade.presentation.components.AdaptiveSheet
import eu.kanade.presentation.theme.colorscheme.AndroidViewColorScheme
import eu.kanade.tachiyomi.databinding.MigrationBottomSheetBinding
import eu.kanade.tachiyomi.ui.browse.migration.MigrationFlags
import eu.kanade.tachiyomi.util.system.toast
Expand Down Expand Up @@ -49,10 +48,7 @@ fun MigrationBottomSheetDialog(
}

// KMK -->
val primaryColor = MaterialTheme.colorScheme.primary.toArgb()
val onSurface = MaterialTheme.colorScheme.onSurface.toArgb()
val surface = MaterialTheme.colorScheme.surface.toArgb()
val textHighlightColor = MaterialTheme.colorScheme.inversePrimary.toArgb()
val colorScheme = AndroidViewColorScheme(MaterialTheme.colorScheme)
// KMK <--

AdaptiveSheet(onDismissRequest = onDismissRequest) {
Expand All @@ -61,75 +57,48 @@ fun MigrationBottomSheetDialog(
val binding = MigrationBottomSheetBinding.inflate(LayoutInflater.from(factoryContext))
state.initPreferences(binding)
// KMK -->
binding.migrateBtn.setBackgroundColor(primaryColor)
binding.dataLabel.setTextColor(primaryColor)
binding.optionsLabel.setTextColor(primaryColor)

val buttonTintList = ColorStateList(
arrayOf(
intArrayOf(android.R.attr.state_checked),
intArrayOf(-android.R.attr.state_checked),
),
intArrayOf(
primaryColor,
onSurface,
),
)

binding.migChapters.buttonTintList = buttonTintList
binding.migCategories.buttonTintList = buttonTintList
binding.migTracking.buttonTintList = buttonTintList
binding.migCustomCover.buttonTintList = buttonTintList
binding.migExtra.buttonTintList = buttonTintList
binding.migDeleteDownloaded.buttonTintList = buttonTintList

binding.radioButton.buttonTintList = buttonTintList
binding.radioButton2.buttonTintList = buttonTintList

val trackTintList = ColorStateList(
arrayOf(
intArrayOf(android.R.attr.state_checked),
intArrayOf(-android.R.attr.state_checked),
),
intArrayOf(
primaryColor,
surface,
),
)

binding.useSmartSearch.trackTintList = trackTintList
binding.extraSearchParam.trackTintList = trackTintList
binding.skipStep.trackTintList = trackTintList
binding.HideNotFoundManga.trackTintList = trackTintList
binding.OnlyShowUpdates.trackTintList = trackTintList

val editTextBackgroundTintList = ColorStateList(
arrayOf(
intArrayOf(android.R.attr.state_focused),
intArrayOf(-android.R.attr.state_focused),
),
intArrayOf(
primaryColor,
onSurface,
),
)
binding.migrateBtn.setBackgroundColor(colorScheme.primary)
binding.dataLabel.setTextColor(colorScheme.primary)
binding.optionsLabel.setTextColor(colorScheme.primary)

binding.migChapters.buttonTintList = colorScheme.checkboxTintList
binding.migCategories.buttonTintList = colorScheme.checkboxTintList
binding.migTracking.buttonTintList = colorScheme.checkboxTintList
binding.migCustomCover.buttonTintList = colorScheme.checkboxTintList
binding.migExtra.buttonTintList = colorScheme.checkboxTintList
binding.migDeleteDownloaded.buttonTintList = colorScheme.checkboxTintList

binding.radioButton.buttonTintList = colorScheme.checkboxTintList
binding.radioButton2.buttonTintList = colorScheme.checkboxTintList

binding.useSmartSearch.trackTintList = colorScheme.trackTintList
binding.extraSearchParam.trackTintList = colorScheme.trackTintList
binding.skipStep.trackTintList = colorScheme.trackTintList
binding.HideNotFoundManga.trackTintList = colorScheme.trackTintList
binding.OnlyShowUpdates.trackTintList = colorScheme.trackTintList

binding.useSmartSearch.thumbTintList = colorScheme.thumbTintList
binding.extraSearchParam.thumbTintList = colorScheme.thumbTintList
binding.skipStep.thumbTintList = colorScheme.thumbTintList
binding.HideNotFoundManga.thumbTintList = colorScheme.thumbTintList
binding.OnlyShowUpdates.thumbTintList = colorScheme.thumbTintList

with(binding.extraSearchParamText) {
highlightColor = textHighlightColor
backgroundTintList = editTextBackgroundTintList
highlightColor = colorScheme.textHighlightColor
backgroundTintList = colorScheme.editTextBackgroundTintList

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
textCursorDrawable = ColorDrawable(primaryColor)
textCursorDrawable = ColorDrawable(colorScheme.primary)
textSelectHandle?.let { drawable ->
drawable.setTint(primaryColor)
drawable.setTint(colorScheme.primary)
setTextSelectHandle(drawable)
}
textSelectHandleLeft?.let { drawable ->
drawable.setTint(primaryColor)
drawable.setTint(colorScheme.primary)
setTextSelectHandleLeft(drawable)
}
textSelectHandleRight?.let { drawable ->
drawable.setTint(primaryColor)
drawable.setTint(colorScheme.primary)
setTextSelectHandleRight(drawable)
}
}
Expand Down
Loading
Loading