Rename
This commit is contained in:
1 parent
b86d90021c
commit
6c0757c91b
972 files changed
+6885
-7321
No files matched your search
@@ -0,0 +1,7 @@
|
||||
@file:Suppress("unused")
|
||||
|
||||
package io.legato.kazusa.lib.theme
|
||||
|
||||
/**
|
||||
* @author Karim Abou Zeid (kabouzeid)
|
||||
*/
|
||||
@@ -0,0 +1,450 @@
|
||||
package io.legato.kazusa.lib.theme
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
import android.graphics.drawable.StateListDrawable
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.annotation.Dimension
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.IntDef
|
||||
import androidx.core.content.ContextCompat
|
||||
|
||||
@Suppress("unused")
|
||||
object Selector {
|
||||
fun shapeBuild(): ShapeSelector {
|
||||
return ShapeSelector()
|
||||
}
|
||||
|
||||
fun colorBuild(): ColorSelector {
|
||||
return ColorSelector()
|
||||
}
|
||||
|
||||
fun drawableBuild(): DrawableSelector {
|
||||
return DrawableSelector()
|
||||
}
|
||||
|
||||
/**
|
||||
* 形状ShapeSelector
|
||||
*
|
||||
* @author hjy
|
||||
* created at 2017/12/11 22:26
|
||||
*/
|
||||
class ShapeSelector {
|
||||
|
||||
private var mShape: Int = 0 //the shape of background
|
||||
private var mDefaultBgColor: Int = 0 //default background color
|
||||
private var mDisabledBgColor: Int = 0 //state_enabled = false
|
||||
private var mPressedBgColor: Int = 0 //state_pressed = true
|
||||
private var mSelectedBgColor: Int = 0 //state_selected = true
|
||||
private var mFocusedBgColor: Int = 0 //state_focused = true
|
||||
private var mCheckedBgColor: Int = 0 //state_checked = true
|
||||
private var mStrokeWidth: Int = 0 //stroke width in pixel
|
||||
private var mDefaultStrokeColor: Int = 0 //default stroke color
|
||||
private var mDisabledStrokeColor: Int = 0 //state_enabled = false
|
||||
private var mPressedStrokeColor: Int = 0 //state_pressed = true
|
||||
private var mSelectedStrokeColor: Int = 0 //state_selected = true
|
||||
private var mFocusedStrokeColor: Int = 0 //state_focused = true
|
||||
private var mCheckedStrokeColor: Int = 0 //state_checked = true
|
||||
private var mCornerRadius: Int = 0 //corner radius
|
||||
|
||||
private var hasSetDisabledBgColor = false
|
||||
private var hasSetPressedBgColor = false
|
||||
private var hasSetSelectedBgColor = false
|
||||
private val hasSetFocusedBgColor = false
|
||||
private var hasSetCheckedBgColor = false
|
||||
|
||||
private var hasSetDisabledStrokeColor = false
|
||||
private var hasSetPressedStrokeColor = false
|
||||
private var hasSetSelectedStrokeColor = false
|
||||
private var hasSetFocusedStrokeColor = false
|
||||
private var hasSetCheckedStrokeColor = false
|
||||
|
||||
@IntDef(
|
||||
GradientDrawable.RECTANGLE,
|
||||
GradientDrawable.OVAL,
|
||||
GradientDrawable.LINE,
|
||||
GradientDrawable.RING
|
||||
)
|
||||
private annotation class Shape
|
||||
|
||||
init {
|
||||
//initialize default values
|
||||
mShape = GradientDrawable.RECTANGLE
|
||||
mDefaultBgColor = Color.TRANSPARENT
|
||||
mDisabledBgColor = Color.TRANSPARENT
|
||||
mPressedBgColor = Color.TRANSPARENT
|
||||
mSelectedBgColor = Color.TRANSPARENT
|
||||
mFocusedBgColor = Color.TRANSPARENT
|
||||
mStrokeWidth = 0
|
||||
mDefaultStrokeColor = Color.TRANSPARENT
|
||||
mDisabledStrokeColor = Color.TRANSPARENT
|
||||
mPressedStrokeColor = Color.TRANSPARENT
|
||||
mSelectedStrokeColor = Color.TRANSPARENT
|
||||
mFocusedStrokeColor = Color.TRANSPARENT
|
||||
mCornerRadius = 0
|
||||
}
|
||||
|
||||
fun setShape(@Shape shape: Int): ShapeSelector {
|
||||
mShape = shape
|
||||
return this
|
||||
}
|
||||
|
||||
fun setDefaultBgColor(@ColorInt color: Int): ShapeSelector {
|
||||
mDefaultBgColor = color
|
||||
if (!hasSetDisabledBgColor)
|
||||
mDisabledBgColor = color
|
||||
if (!hasSetPressedBgColor)
|
||||
mPressedBgColor = color
|
||||
if (!hasSetSelectedBgColor)
|
||||
mSelectedBgColor = color
|
||||
if (!hasSetFocusedBgColor)
|
||||
mFocusedBgColor = color
|
||||
return this
|
||||
}
|
||||
|
||||
fun setDisabledBgColor(@ColorInt color: Int): ShapeSelector {
|
||||
mDisabledBgColor = color
|
||||
hasSetDisabledBgColor = true
|
||||
return this
|
||||
}
|
||||
|
||||
fun setPressedBgColor(@ColorInt color: Int): ShapeSelector {
|
||||
mPressedBgColor = color
|
||||
hasSetPressedBgColor = true
|
||||
return this
|
||||
}
|
||||
|
||||
fun setSelectedBgColor(@ColorInt color: Int): ShapeSelector {
|
||||
mSelectedBgColor = color
|
||||
hasSetSelectedBgColor = true
|
||||
return this
|
||||
}
|
||||
|
||||
fun setFocusedBgColor(@ColorInt color: Int): ShapeSelector {
|
||||
mFocusedBgColor = color
|
||||
hasSetPressedBgColor = true
|
||||
return this
|
||||
}
|
||||
|
||||
fun setCheckedBgColor(@ColorInt color: Int): ShapeSelector {
|
||||
mCheckedBgColor = color
|
||||
hasSetCheckedBgColor = true
|
||||
return this
|
||||
}
|
||||
|
||||
fun setStrokeWidth(@Dimension width: Int): ShapeSelector {
|
||||
mStrokeWidth = width
|
||||
return this
|
||||
}
|
||||
|
||||
fun setDefaultStrokeColor(@ColorInt color: Int): ShapeSelector {
|
||||
mDefaultStrokeColor = color
|
||||
if (!hasSetDisabledStrokeColor)
|
||||
mDisabledStrokeColor = color
|
||||
if (!hasSetPressedStrokeColor)
|
||||
mPressedStrokeColor = color
|
||||
if (!hasSetSelectedStrokeColor)
|
||||
mSelectedStrokeColor = color
|
||||
if (!hasSetFocusedStrokeColor)
|
||||
mFocusedStrokeColor = color
|
||||
return this
|
||||
}
|
||||
|
||||
fun setDisabledStrokeColor(@ColorInt color: Int): ShapeSelector {
|
||||
mDisabledStrokeColor = color
|
||||
hasSetDisabledStrokeColor = true
|
||||
return this
|
||||
}
|
||||
|
||||
fun setPressedStrokeColor(@ColorInt color: Int): ShapeSelector {
|
||||
mPressedStrokeColor = color
|
||||
hasSetPressedStrokeColor = true
|
||||
return this
|
||||
}
|
||||
|
||||
fun setSelectedStrokeColor(@ColorInt color: Int): ShapeSelector {
|
||||
mSelectedStrokeColor = color
|
||||
hasSetSelectedStrokeColor = true
|
||||
return this
|
||||
}
|
||||
|
||||
fun setCheckedStrokeColor(@ColorInt color: Int): ShapeSelector {
|
||||
mCheckedStrokeColor = color
|
||||
hasSetCheckedStrokeColor = true
|
||||
return this
|
||||
}
|
||||
|
||||
fun setFocusedStrokeColor(@ColorInt color: Int): ShapeSelector {
|
||||
mFocusedStrokeColor = color
|
||||
hasSetFocusedStrokeColor = true
|
||||
return this
|
||||
}
|
||||
|
||||
fun setCornerRadius(@Dimension radius: Int): ShapeSelector {
|
||||
mCornerRadius = radius
|
||||
return this
|
||||
}
|
||||
|
||||
fun create(): StateListDrawable {
|
||||
val selector = StateListDrawable()
|
||||
|
||||
//enabled = false
|
||||
if (hasSetDisabledBgColor || hasSetDisabledStrokeColor) {
|
||||
val disabledShape = getItemShape(
|
||||
mShape, mCornerRadius,
|
||||
mDisabledBgColor, mStrokeWidth, mDisabledStrokeColor
|
||||
)
|
||||
selector.addState(intArrayOf(-android.R.attr.state_enabled), disabledShape)
|
||||
}
|
||||
|
||||
//pressed = true
|
||||
if (hasSetPressedBgColor || hasSetPressedStrokeColor) {
|
||||
val pressedShape = getItemShape(
|
||||
mShape, mCornerRadius,
|
||||
mPressedBgColor, mStrokeWidth, mPressedStrokeColor
|
||||
)
|
||||
selector.addState(intArrayOf(android.R.attr.state_pressed), pressedShape)
|
||||
}
|
||||
|
||||
//selected = true
|
||||
if (hasSetSelectedBgColor || hasSetSelectedStrokeColor) {
|
||||
val selectedShape = getItemShape(
|
||||
mShape, mCornerRadius,
|
||||
mSelectedBgColor, mStrokeWidth, mSelectedStrokeColor
|
||||
)
|
||||
selector.addState(intArrayOf(android.R.attr.state_selected), selectedShape)
|
||||
}
|
||||
|
||||
//focused = true
|
||||
if (hasSetFocusedBgColor || hasSetFocusedStrokeColor) {
|
||||
val focusedShape = getItemShape(
|
||||
mShape, mCornerRadius,
|
||||
mFocusedBgColor, mStrokeWidth, mFocusedStrokeColor
|
||||
)
|
||||
selector.addState(intArrayOf(android.R.attr.state_focused), focusedShape)
|
||||
}
|
||||
|
||||
//checked = true
|
||||
if (hasSetCheckedBgColor || hasSetCheckedStrokeColor) {
|
||||
val checkedShape = getItemShape(
|
||||
mShape, mCornerRadius,
|
||||
mCheckedBgColor, mStrokeWidth, mCheckedStrokeColor
|
||||
)
|
||||
selector.addState(intArrayOf(android.R.attr.state_checked), checkedShape)
|
||||
}
|
||||
|
||||
//default
|
||||
val defaultShape = getItemShape(
|
||||
mShape, mCornerRadius,
|
||||
mDefaultBgColor, mStrokeWidth, mDefaultStrokeColor
|
||||
)
|
||||
selector.addState(intArrayOf(), defaultShape)
|
||||
|
||||
return selector
|
||||
}
|
||||
|
||||
private fun getItemShape(
|
||||
shape: Int, cornerRadius: Int,
|
||||
solidColor: Int, strokeWidth: Int, strokeColor: Int
|
||||
): GradientDrawable {
|
||||
val drawable = GradientDrawable()
|
||||
drawable.shape = shape
|
||||
drawable.setStroke(strokeWidth, strokeColor)
|
||||
drawable.cornerRadius = cornerRadius.toFloat()
|
||||
drawable.setColor(solidColor)
|
||||
return drawable
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 资源DrawableSelector
|
||||
*
|
||||
* @author hjy
|
||||
* created at 2017/12/11 22:34
|
||||
*/
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
class DrawableSelector {
|
||||
|
||||
private var mDefaultDrawable: Drawable? = null
|
||||
private var mDisabledDrawable: Drawable? = null
|
||||
private var mPressedDrawable: Drawable? = null
|
||||
private var mSelectedDrawable: Drawable? = null
|
||||
private var mFocusedDrawable: Drawable? = null
|
||||
|
||||
private var hasSetDisabledDrawable = false
|
||||
private var hasSetPressedDrawable = false
|
||||
private var hasSetSelectedDrawable = false
|
||||
private var hasSetFocusedDrawable = false
|
||||
|
||||
init {
|
||||
mDefaultDrawable = ColorDrawable(Color.TRANSPARENT)
|
||||
}
|
||||
|
||||
fun setDefaultDrawable(drawable: Drawable?): DrawableSelector {
|
||||
mDefaultDrawable = drawable
|
||||
if (!hasSetDisabledDrawable)
|
||||
mDisabledDrawable = drawable
|
||||
if (!hasSetPressedDrawable)
|
||||
mPressedDrawable = drawable
|
||||
if (!hasSetSelectedDrawable)
|
||||
mSelectedDrawable = drawable
|
||||
if (!hasSetFocusedDrawable)
|
||||
mFocusedDrawable = drawable
|
||||
return this
|
||||
}
|
||||
|
||||
fun setDisabledDrawable(drawable: Drawable?): DrawableSelector {
|
||||
mDisabledDrawable = drawable
|
||||
hasSetDisabledDrawable = true
|
||||
return this
|
||||
}
|
||||
|
||||
fun setPressedDrawable(drawable: Drawable?): DrawableSelector {
|
||||
mPressedDrawable = drawable
|
||||
hasSetPressedDrawable = true
|
||||
return this
|
||||
}
|
||||
|
||||
fun setSelectedDrawable(drawable: Drawable?): DrawableSelector {
|
||||
mSelectedDrawable = drawable
|
||||
hasSetSelectedDrawable = true
|
||||
return this
|
||||
}
|
||||
|
||||
fun setFocusedDrawable(drawable: Drawable?): DrawableSelector {
|
||||
mFocusedDrawable = drawable
|
||||
hasSetFocusedDrawable = true
|
||||
return this
|
||||
}
|
||||
|
||||
fun create(): StateListDrawable {
|
||||
val selector = StateListDrawable()
|
||||
if (hasSetDisabledDrawable)
|
||||
selector.addState(intArrayOf(-android.R.attr.state_enabled), mDisabledDrawable)
|
||||
if (hasSetPressedDrawable)
|
||||
selector.addState(intArrayOf(android.R.attr.state_pressed), mPressedDrawable)
|
||||
if (hasSetSelectedDrawable)
|
||||
selector.addState(intArrayOf(android.R.attr.state_selected), mSelectedDrawable)
|
||||
if (hasSetFocusedDrawable)
|
||||
selector.addState(intArrayOf(android.R.attr.state_focused), mFocusedDrawable)
|
||||
selector.addState(intArrayOf(), mDefaultDrawable)
|
||||
return selector
|
||||
}
|
||||
|
||||
fun setDefaultDrawable(context: Context, @DrawableRes drawableRes: Int): DrawableSelector {
|
||||
return setDefaultDrawable(ContextCompat.getDrawable(context, drawableRes))
|
||||
}
|
||||
|
||||
fun setDisabledDrawable(context: Context, @DrawableRes drawableRes: Int): DrawableSelector {
|
||||
return setDisabledDrawable(ContextCompat.getDrawable(context, drawableRes))
|
||||
}
|
||||
|
||||
fun setPressedDrawable(context: Context, @DrawableRes drawableRes: Int): DrawableSelector {
|
||||
return setPressedDrawable(ContextCompat.getDrawable(context, drawableRes))
|
||||
}
|
||||
|
||||
fun setSelectedDrawable(context: Context, @DrawableRes drawableRes: Int): DrawableSelector {
|
||||
return setSelectedDrawable(ContextCompat.getDrawable(context, drawableRes))
|
||||
}
|
||||
|
||||
fun setFocusedDrawable(context: Context, @DrawableRes drawableRes: Int): DrawableSelector {
|
||||
return setFocusedDrawable(ContextCompat.getDrawable(context, drawableRes))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 颜色ColorSelector
|
||||
*
|
||||
* @author hjy
|
||||
* created at 2017/12/11 22:26
|
||||
*/
|
||||
class ColorSelector {
|
||||
|
||||
private var mDefaultColor: Int = 0
|
||||
private var mDisabledColor: Int = 0
|
||||
private var mPressedColor: Int = 0
|
||||
private var mSelectedColor: Int = 0
|
||||
private var mFocusedColor: Int = 0
|
||||
private var mCheckedColor: Int = 0
|
||||
|
||||
private var hasSetDisabledColor = false
|
||||
private var hasSetPressedColor = false
|
||||
private var hasSetSelectedColor = false
|
||||
private var hasSetFocusedColor = false
|
||||
private var hasSetCheckedColor = false
|
||||
|
||||
init {
|
||||
mDefaultColor = Color.BLACK
|
||||
mDisabledColor = Color.GRAY
|
||||
mPressedColor = Color.BLACK
|
||||
mSelectedColor = Color.BLACK
|
||||
mFocusedColor = Color.BLACK
|
||||
}
|
||||
|
||||
fun setDefaultColor(@ColorInt color: Int): ColorSelector {
|
||||
mDefaultColor = color
|
||||
if (!hasSetDisabledColor)
|
||||
mDisabledColor = color
|
||||
if (!hasSetPressedColor)
|
||||
mPressedColor = color
|
||||
if (!hasSetSelectedColor)
|
||||
mSelectedColor = color
|
||||
if (!hasSetFocusedColor)
|
||||
mFocusedColor = color
|
||||
return this
|
||||
}
|
||||
|
||||
fun setDisabledColor(@ColorInt color: Int): ColorSelector {
|
||||
mDisabledColor = color
|
||||
hasSetDisabledColor = true
|
||||
return this
|
||||
}
|
||||
|
||||
fun setPressedColor(@ColorInt color: Int): ColorSelector {
|
||||
mPressedColor = color
|
||||
hasSetPressedColor = true
|
||||
return this
|
||||
}
|
||||
|
||||
fun setSelectedColor(@ColorInt color: Int): ColorSelector {
|
||||
mSelectedColor = color
|
||||
hasSetSelectedColor = true
|
||||
return this
|
||||
}
|
||||
|
||||
fun setFocusedColor(@ColorInt color: Int): ColorSelector {
|
||||
mFocusedColor = color
|
||||
hasSetFocusedColor = true
|
||||
return this
|
||||
}
|
||||
|
||||
fun setCheckedColor(@ColorInt color: Int): ColorSelector {
|
||||
mCheckedColor = color
|
||||
hasSetCheckedColor = true
|
||||
return this
|
||||
}
|
||||
|
||||
fun create(): ColorStateList {
|
||||
val colors = intArrayOf(
|
||||
if (hasSetDisabledColor) mDisabledColor else mDefaultColor,
|
||||
if (hasSetPressedColor) mPressedColor else mDefaultColor,
|
||||
if (hasSetSelectedColor) mSelectedColor else mDefaultColor,
|
||||
if (hasSetFocusedColor) mFocusedColor else mDefaultColor,
|
||||
if (hasSetCheckedColor) mCheckedColor else mDefaultColor,
|
||||
mDefaultColor
|
||||
)
|
||||
val states = arrayOfNulls<IntArray>(6)
|
||||
states[0] = intArrayOf(-android.R.attr.state_enabled)
|
||||
states[1] = intArrayOf(android.R.attr.state_pressed)
|
||||
states[2] = intArrayOf(android.R.attr.state_selected)
|
||||
states[3] = intArrayOf(android.R.attr.state_focused)
|
||||
states[4] = intArrayOf(android.R.attr.state_checked)
|
||||
states[5] = intArrayOf()
|
||||
return ColorStateList(states, colors)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,354 @@
|
||||
package io.legato.kazusa.lib.theme
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.graphics.Color
|
||||
import androidx.annotation.AttrRes
|
||||
import androidx.annotation.CheckResult
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.annotation.ColorRes
|
||||
import androidx.core.content.ContextCompat
|
||||
import io.legato.kazusa.utils.ColorUtils
|
||||
import splitties.init.appCtx
|
||||
import androidx.core.graphics.toColorInt
|
||||
|
||||
/**
|
||||
* @author Aidan Follestad (afollestad), Karim Abou Zeid (kabouzeid)
|
||||
*/
|
||||
@Suppress("unused")
|
||||
class ThemeStore @SuppressLint("CommitPrefEdits")
|
||||
private constructor(private val mContext: Context) : ThemeStoreInterface {
|
||||
|
||||
private val mEditor = prefs(mContext).edit()
|
||||
|
||||
// override fun enableDynamicColors(context: Context, enable: Boolean): ThemeStore {
|
||||
// mEditor.putBoolean(ThemeStorePrefKeys.KEY_DYNAMIC_COLORS_ENABLED, enable)
|
||||
// if (enable && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
// // 使用系统动态颜色
|
||||
// val dynamicColors = DynamicColorsOptions.Builder()
|
||||
// .setThemeOverlay(R.style.Theme_App_Dynamic)
|
||||
// .build()
|
||||
// DynamicColors.applyToActivitiesIfAvailable(context.applicationContext, dynamicColors)
|
||||
// }
|
||||
// return this
|
||||
// }
|
||||
|
||||
override fun primaryColor(@ColorInt color: Int): ThemeStore {
|
||||
mEditor.putInt(ThemeStorePrefKeys.KEY_PRIMARY_COLOR, color)
|
||||
if (autoGeneratePrimaryDark(mContext))
|
||||
primaryColorDark(ColorUtils.darkenColor(color))
|
||||
return this
|
||||
}
|
||||
|
||||
override fun primaryColorRes(@ColorRes colorRes: Int): ThemeStore {
|
||||
return primaryColor(ContextCompat.getColor(mContext, colorRes))
|
||||
}
|
||||
|
||||
override fun primaryColorAttr(@AttrRes colorAttr: Int): ThemeStore {
|
||||
return primaryColor(ThemeUtils.resolveColor(mContext, colorAttr))
|
||||
}
|
||||
|
||||
override fun primaryColorDark(@ColorInt color: Int): ThemeStore {
|
||||
mEditor.putInt(ThemeStorePrefKeys.KEY_PRIMARY_COLOR_DARK, color)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun primaryColorDarkRes(@ColorRes colorRes: Int): ThemeStore {
|
||||
return primaryColorDark(ContextCompat.getColor(mContext, colorRes))
|
||||
}
|
||||
|
||||
override fun primaryColorDarkAttr(@AttrRes colorAttr: Int): ThemeStore {
|
||||
return primaryColorDark(ThemeUtils.resolveColor(mContext, colorAttr))
|
||||
}
|
||||
|
||||
override fun accentColor(@ColorInt color: Int): ThemeStore {
|
||||
mEditor.putInt(ThemeStorePrefKeys.KEY_ACCENT_COLOR, color)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun accentColorRes(@ColorRes colorRes: Int): ThemeStore {
|
||||
return accentColor(ContextCompat.getColor(mContext, colorRes))
|
||||
}
|
||||
|
||||
override fun accentColorAttr(@AttrRes colorAttr: Int): ThemeStore {
|
||||
return accentColor(ThemeUtils.resolveColor(mContext, colorAttr))
|
||||
}
|
||||
|
||||
override fun statusBarColor(@ColorInt color: Int): ThemeStore {
|
||||
mEditor.putInt(ThemeStorePrefKeys.KEY_STATUS_BAR_COLOR, color)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun statusBarColorRes(@ColorRes colorRes: Int): ThemeStore {
|
||||
return statusBarColor(ContextCompat.getColor(mContext, colorRes))
|
||||
}
|
||||
|
||||
override fun statusBarColorAttr(@AttrRes colorAttr: Int): ThemeStore {
|
||||
return statusBarColor(ThemeUtils.resolveColor(mContext, colorAttr))
|
||||
}
|
||||
|
||||
override fun navigationBarColor(@ColorInt color: Int): ThemeStore {
|
||||
mEditor.putInt(ThemeStorePrefKeys.KEY_NAVIGATION_BAR_COLOR, color)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun navigationBarColorRes(@ColorRes colorRes: Int): ThemeStore {
|
||||
return navigationBarColor(ContextCompat.getColor(mContext, colorRes))
|
||||
}
|
||||
|
||||
override fun navigationBarColorAttr(@AttrRes colorAttr: Int): ThemeStore {
|
||||
return navigationBarColor(ThemeUtils.resolveColor(mContext, colorAttr))
|
||||
}
|
||||
|
||||
override fun textColorPrimary(@ColorInt color: Int): ThemeStore {
|
||||
mEditor.putInt(ThemeStorePrefKeys.KEY_TEXT_COLOR_PRIMARY, color)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun textColorPrimaryRes(@ColorRes colorRes: Int): ThemeStore {
|
||||
return textColorPrimary(ContextCompat.getColor(mContext, colorRes))
|
||||
}
|
||||
|
||||
override fun textColorPrimaryAttr(@AttrRes colorAttr: Int): ThemeStore {
|
||||
return textColorPrimary(ThemeUtils.resolveColor(mContext, colorAttr))
|
||||
}
|
||||
|
||||
override fun textColorPrimaryInverse(@ColorInt color: Int): ThemeStore {
|
||||
mEditor.putInt(ThemeStorePrefKeys.KEY_TEXT_COLOR_PRIMARY_INVERSE, color)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun textColorPrimaryInverseRes(@ColorRes colorRes: Int): ThemeStore {
|
||||
return textColorPrimaryInverse(ContextCompat.getColor(mContext, colorRes))
|
||||
}
|
||||
|
||||
override fun textColorPrimaryInverseAttr(@AttrRes colorAttr: Int): ThemeStore {
|
||||
return textColorPrimaryInverse(ThemeUtils.resolveColor(mContext, colorAttr))
|
||||
}
|
||||
|
||||
override fun textColorSecondary(@ColorInt color: Int): ThemeStore {
|
||||
mEditor.putInt(ThemeStorePrefKeys.KEY_TEXT_COLOR_SECONDARY, color)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun textColorSecondaryRes(@ColorRes colorRes: Int): ThemeStore {
|
||||
return textColorSecondary(ContextCompat.getColor(mContext, colorRes))
|
||||
}
|
||||
|
||||
override fun textColorSecondaryAttr(@AttrRes colorAttr: Int): ThemeStore {
|
||||
return textColorSecondary(ThemeUtils.resolveColor(mContext, colorAttr))
|
||||
}
|
||||
|
||||
override fun textColorSecondaryInverse(@ColorInt color: Int): ThemeStore {
|
||||
mEditor.putInt(ThemeStorePrefKeys.KEY_TEXT_COLOR_SECONDARY_INVERSE, color)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun textColorSecondaryInverseRes(@ColorRes colorRes: Int): ThemeStore {
|
||||
return textColorSecondaryInverse(ContextCompat.getColor(mContext, colorRes))
|
||||
}
|
||||
|
||||
override fun textColorSecondaryInverseAttr(@AttrRes colorAttr: Int): ThemeStore {
|
||||
return textColorSecondaryInverse(ThemeUtils.resolveColor(mContext, colorAttr))
|
||||
}
|
||||
|
||||
override fun backgroundColor(color: Int): ThemeStore {
|
||||
mEditor.putInt(ThemeStorePrefKeys.KEY_BACKGROUND_COLOR, color)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun bottomBackground(color: Int): ThemeStore {
|
||||
mEditor.putInt(ThemeStorePrefKeys.KEY_BOTTOM_BACKGROUND, color)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun autoGeneratePrimaryDark(autoGenerate: Boolean): ThemeStore {
|
||||
mEditor.putBoolean(ThemeStorePrefKeys.KEY_AUTO_GENERATE_PRIMARYDARK, autoGenerate)
|
||||
return this
|
||||
}
|
||||
|
||||
// Commit method
|
||||
|
||||
override fun apply() {
|
||||
mEditor.putLong(ThemeStorePrefKeys.VALUES_CHANGED, System.currentTimeMillis())
|
||||
.putBoolean(ThemeStorePrefKeys.IS_CONFIGURED_KEY, true)
|
||||
.apply()
|
||||
accentColor = accentColor()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
var accentColor = accentColor()
|
||||
|
||||
fun editTheme(context: Context): ThemeStore {
|
||||
return ThemeStore(context)
|
||||
}
|
||||
|
||||
// Static getters
|
||||
|
||||
@CheckResult
|
||||
internal fun prefs(context: Context): SharedPreferences {
|
||||
return context.getSharedPreferences(
|
||||
ThemeStorePrefKeys.CONFIG_PREFS_KEY_DEFAULT,
|
||||
Context.MODE_PRIVATE
|
||||
)
|
||||
}
|
||||
|
||||
fun markChanged(context: Context) {
|
||||
ThemeStore(context).apply()
|
||||
}
|
||||
|
||||
@CheckResult
|
||||
@ColorInt
|
||||
fun primaryColor(context: Context = appCtx): Int {
|
||||
return prefs(context).getInt(
|
||||
ThemeStorePrefKeys.KEY_PRIMARY_COLOR,
|
||||
ThemeUtils.resolveColor(
|
||||
context,
|
||||
androidx.appcompat.R.attr.colorPrimary,
|
||||
"#455A64".toColorInt()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@CheckResult
|
||||
@ColorInt
|
||||
fun primaryColorDark(context: Context): Int {
|
||||
return prefs(context).getInt(
|
||||
ThemeStorePrefKeys.KEY_PRIMARY_COLOR_DARK,
|
||||
ThemeUtils.resolveColor(
|
||||
context,
|
||||
androidx.appcompat.R.attr.colorPrimaryDark,
|
||||
Color.parseColor("#37474F")
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@CheckResult
|
||||
@ColorInt
|
||||
fun accentColor(context: Context = appCtx): Int {
|
||||
return prefs(context).getInt(
|
||||
ThemeStorePrefKeys.KEY_ACCENT_COLOR,
|
||||
ThemeUtils.resolveColor(
|
||||
context,
|
||||
androidx.appcompat.R.attr.colorAccent,
|
||||
Color.parseColor("#263238")
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@CheckResult
|
||||
@ColorInt
|
||||
fun statusBarColor(context: Context, transparent: Boolean): Int {
|
||||
return if (transparent) {
|
||||
prefs(context).getInt(
|
||||
ThemeStorePrefKeys.KEY_STATUS_BAR_COLOR,
|
||||
primaryColor(context)
|
||||
)
|
||||
} else {
|
||||
prefs(context).getInt(
|
||||
ThemeStorePrefKeys.KEY_STATUS_BAR_COLOR,
|
||||
primaryColorDark(context)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@CheckResult
|
||||
@ColorInt
|
||||
fun navigationBarColor(context: Context): Int {
|
||||
return prefs(context).getInt(
|
||||
ThemeStorePrefKeys.KEY_NAVIGATION_BAR_COLOR,
|
||||
bottomBackground(context)
|
||||
)
|
||||
}
|
||||
|
||||
@CheckResult
|
||||
@ColorInt
|
||||
fun textColorPrimary(context: Context): Int {
|
||||
return prefs(context).getInt(
|
||||
ThemeStorePrefKeys.KEY_TEXT_COLOR_PRIMARY,
|
||||
ThemeUtils.resolveColor(context, android.R.attr.textColorPrimary)
|
||||
)
|
||||
}
|
||||
|
||||
@CheckResult
|
||||
@ColorInt
|
||||
fun textColorPrimaryInverse(context: Context): Int {
|
||||
return prefs(context).getInt(
|
||||
ThemeStorePrefKeys.KEY_TEXT_COLOR_PRIMARY_INVERSE,
|
||||
ThemeUtils.resolveColor(context, android.R.attr.textColorPrimaryInverse)
|
||||
)
|
||||
}
|
||||
|
||||
@CheckResult
|
||||
@ColorInt
|
||||
fun textColorSecondary(context: Context): Int {
|
||||
return prefs(context).getInt(
|
||||
ThemeStorePrefKeys.KEY_TEXT_COLOR_SECONDARY,
|
||||
ThemeUtils.resolveColor(context, android.R.attr.textColorSecondary)
|
||||
)
|
||||
}
|
||||
|
||||
@CheckResult
|
||||
@ColorInt
|
||||
fun textColorSecondaryInverse(context: Context): Int {
|
||||
return prefs(context).getInt(
|
||||
ThemeStorePrefKeys.KEY_TEXT_COLOR_SECONDARY_INVERSE,
|
||||
ThemeUtils.resolveColor(context, android.R.attr.textColorSecondaryInverse)
|
||||
)
|
||||
}
|
||||
|
||||
@CheckResult
|
||||
@ColorInt
|
||||
fun backgroundColor(context: Context = appCtx): Int {
|
||||
return prefs(context).getInt(
|
||||
ThemeStorePrefKeys.KEY_BACKGROUND_COLOR,
|
||||
ThemeUtils.resolveColor(context, android.R.attr.colorBackground)
|
||||
)
|
||||
}
|
||||
|
||||
@CheckResult
|
||||
@ColorInt
|
||||
fun bottomBackground(context: Context = appCtx): Int {
|
||||
return prefs(context).getInt(
|
||||
ThemeStorePrefKeys.KEY_BOTTOM_BACKGROUND,
|
||||
ThemeUtils.resolveColor(context, android.R.attr.colorBackground)
|
||||
)
|
||||
}
|
||||
|
||||
@CheckResult
|
||||
fun coloredStatusBar(context: Context): Boolean {
|
||||
return prefs(context).getBoolean(
|
||||
ThemeStorePrefKeys.KEY_APPLY_PRIMARYDARK_STATUSBAR,
|
||||
true
|
||||
)
|
||||
}
|
||||
|
||||
@CheckResult
|
||||
fun coloredNavigationBar(context: Context): Boolean {
|
||||
return prefs(context).getBoolean(ThemeStorePrefKeys.KEY_APPLY_PRIMARY_NAVBAR, false)
|
||||
}
|
||||
|
||||
@CheckResult
|
||||
fun autoGeneratePrimaryDark(context: Context): Boolean {
|
||||
return prefs(context).getBoolean(ThemeStorePrefKeys.KEY_AUTO_GENERATE_PRIMARYDARK, true)
|
||||
}
|
||||
|
||||
@CheckResult
|
||||
fun isConfigured(context: Context): Boolean {
|
||||
return prefs(context).getBoolean(ThemeStorePrefKeys.IS_CONFIGURED_KEY, false)
|
||||
}
|
||||
|
||||
@SuppressLint("CommitPrefEdits")
|
||||
fun isConfigured(context: Context, version: Int): Boolean {
|
||||
val prefs = prefs(context)
|
||||
val lastVersion = prefs.getInt(ThemeStorePrefKeys.IS_CONFIGURED_VERSION_KEY, -1)
|
||||
if (version > lastVersion) {
|
||||
prefs.edit().putInt(ThemeStorePrefKeys.IS_CONFIGURED_VERSION_KEY, version).apply()
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package io.legato.kazusa.lib.theme
|
||||
|
||||
|
||||
import androidx.annotation.AttrRes
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.annotation.ColorRes
|
||||
|
||||
/**
|
||||
* @author Aidan Follestad (afollestad), Karim Abou Zeid (kabouzeid)
|
||||
*/
|
||||
internal interface ThemeStoreInterface {
|
||||
|
||||
// Primary colors
|
||||
|
||||
fun primaryColor(@ColorInt color: Int): ThemeStore
|
||||
|
||||
fun primaryColorRes(@ColorRes colorRes: Int): ThemeStore
|
||||
|
||||
fun primaryColorAttr(@AttrRes colorAttr: Int): ThemeStore
|
||||
|
||||
fun autoGeneratePrimaryDark(autoGenerate: Boolean): ThemeStore
|
||||
|
||||
fun primaryColorDark(@ColorInt color: Int): ThemeStore
|
||||
|
||||
fun primaryColorDarkRes(@ColorRes colorRes: Int): ThemeStore
|
||||
|
||||
fun primaryColorDarkAttr(@AttrRes colorAttr: Int): ThemeStore
|
||||
|
||||
// Accent colors
|
||||
|
||||
fun accentColor(@ColorInt color: Int): ThemeStore
|
||||
|
||||
fun accentColorRes(@ColorRes colorRes: Int): ThemeStore
|
||||
|
||||
fun accentColorAttr(@AttrRes colorAttr: Int): ThemeStore
|
||||
|
||||
// Status bar color
|
||||
|
||||
fun statusBarColor(@ColorInt color: Int): ThemeStore
|
||||
|
||||
fun statusBarColorRes(@ColorRes colorRes: Int): ThemeStore
|
||||
|
||||
fun statusBarColorAttr(@AttrRes colorAttr: Int): ThemeStore
|
||||
|
||||
// Navigation bar color
|
||||
|
||||
fun navigationBarColor(@ColorInt color: Int): ThemeStore
|
||||
|
||||
fun navigationBarColorRes(@ColorRes colorRes: Int): ThemeStore
|
||||
|
||||
fun navigationBarColorAttr(@AttrRes colorAttr: Int): ThemeStore
|
||||
|
||||
// Primary text color
|
||||
|
||||
fun textColorPrimary(@ColorInt color: Int): ThemeStore
|
||||
|
||||
fun textColorPrimaryRes(@ColorRes colorRes: Int): ThemeStore
|
||||
|
||||
fun textColorPrimaryAttr(@AttrRes colorAttr: Int): ThemeStore
|
||||
|
||||
fun textColorPrimaryInverse(@ColorInt color: Int): ThemeStore
|
||||
|
||||
fun textColorPrimaryInverseRes(@ColorRes colorRes: Int): ThemeStore
|
||||
|
||||
fun textColorPrimaryInverseAttr(@AttrRes colorAttr: Int): ThemeStore
|
||||
|
||||
// Secondary text color
|
||||
|
||||
fun textColorSecondary(@ColorInt color: Int): ThemeStore
|
||||
|
||||
fun textColorSecondaryRes(@ColorRes colorRes: Int): ThemeStore
|
||||
|
||||
fun textColorSecondaryAttr(@AttrRes colorAttr: Int): ThemeStore
|
||||
|
||||
fun textColorSecondaryInverse(@ColorInt color: Int): ThemeStore
|
||||
|
||||
fun textColorSecondaryInverseRes(@ColorRes colorRes: Int): ThemeStore
|
||||
|
||||
fun textColorSecondaryInverseAttr(@AttrRes colorAttr: Int): ThemeStore
|
||||
|
||||
// Background
|
||||
|
||||
fun backgroundColor(@ColorInt color: Int): ThemeStore
|
||||
|
||||
fun bottomBackground(@ColorInt color: Int): ThemeStore
|
||||
|
||||
// Commit/apply
|
||||
|
||||
fun apply()
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package io.legato.kazusa.lib.theme
|
||||
|
||||
/**
|
||||
* @author Aidan Follestad (afollestad), Karim Abou Zeid (kabouzeid)
|
||||
*/
|
||||
object ThemeStorePrefKeys {
|
||||
const val KEY_DYNAMIC_COLORS_ENABLED = ""
|
||||
|
||||
const val CONFIG_PREFS_KEY_DEFAULT = "app_themes"
|
||||
const val IS_CONFIGURED_KEY = "is_configured"
|
||||
const val IS_CONFIGURED_VERSION_KEY = "is_configured_version"
|
||||
const val VALUES_CHANGED = "values_changed"
|
||||
|
||||
const val KEY_PRIMARY_COLOR = "primary_color"
|
||||
const val KEY_PRIMARY_COLOR_DARK = "primary_color_dark"
|
||||
const val KEY_ACCENT_COLOR = "accent_color"
|
||||
const val KEY_STATUS_BAR_COLOR = "status_bar_color"
|
||||
const val KEY_NAVIGATION_BAR_COLOR = "navigation_bar_color"
|
||||
|
||||
const val KEY_TEXT_COLOR_PRIMARY = "text_color_primary"
|
||||
const val KEY_TEXT_COLOR_PRIMARY_INVERSE = "text_color_primary_inverse"
|
||||
const val KEY_TEXT_COLOR_SECONDARY = "text_color_secondary"
|
||||
const val KEY_TEXT_COLOR_SECONDARY_INVERSE = "text_color_secondary_inverse"
|
||||
|
||||
const val KEY_BACKGROUND_COLOR = "backgroundColor"
|
||||
const val KEY_BOTTOM_BACKGROUND = "bottomBackground"
|
||||
|
||||
const val KEY_APPLY_PRIMARYDARK_STATUSBAR = "apply_primarydark_statusbar"
|
||||
const val KEY_APPLY_PRIMARY_NAVBAR = "apply_primary_navbar"
|
||||
const val KEY_AUTO_GENERATE_PRIMARYDARK = "auto_generate_primarydark"
|
||||
|
||||
const val KEY_COLOR_PRIMARY = "key_color_primary"
|
||||
const val KEY_COLOR_ON_PRIMARY = "key_color_on_primary"
|
||||
const val KEY_COLOR_PRIMARY_CONTAINER = "key_color_primary_container"
|
||||
const val KEY_COLOR_ON_PRIMARY_CONTAINER = "key_color_on_primary_container"
|
||||
const val KEY_COLOR_SECONDARY = "key_color_secondary"
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package io.legato.kazusa.lib.theme
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.Drawable
|
||||
import androidx.annotation.AttrRes
|
||||
|
||||
/**
|
||||
* @author Aidan Follestad (afollestad)
|
||||
*/
|
||||
object ThemeUtils {
|
||||
|
||||
@JvmOverloads
|
||||
fun resolveColor(context: Context, @AttrRes attr: Int, fallback: Int = 0): Int {
|
||||
val a = context.theme.obtainStyledAttributes(intArrayOf(attr))
|
||||
return try {
|
||||
a.getColor(0, fallback)
|
||||
} catch (e: Exception) {
|
||||
fallback
|
||||
} finally {
|
||||
a.recycle()
|
||||
}
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
fun resolveFloat(context: Context, @AttrRes attr: Int, fallback: Float = 0.0f): Float {
|
||||
val a = context.theme.obtainStyledAttributes(intArrayOf(attr))
|
||||
return try {
|
||||
a.getFloat(0, fallback)
|
||||
} catch (e: Exception) {
|
||||
fallback
|
||||
} finally {
|
||||
a.recycle()
|
||||
}
|
||||
}
|
||||
|
||||
fun resolveDrawable(context: Context, @AttrRes attr: Int): Drawable? {
|
||||
val a = context.theme.obtainStyledAttributes(intArrayOf(attr))
|
||||
return try {
|
||||
a.getDrawable(0)
|
||||
} finally {
|
||||
a.recycle()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,487 @@
|
||||
package io.legato.kazusa.lib.theme
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.PorterDuff
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.graphics.drawable.RippleDrawable
|
||||
import android.view.View
|
||||
import android.widget.Button
|
||||
import android.widget.CheckBox
|
||||
import android.widget.CheckedTextView
|
||||
import android.widget.EditText
|
||||
import android.widget.ImageView
|
||||
import android.widget.ProgressBar
|
||||
import android.widget.RadioButton
|
||||
import android.widget.SeekBar
|
||||
import android.widget.Switch
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.CheckResult
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.appcompat.widget.AppCompatEditText
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.appcompat.widget.SwitchCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.graphics.drawable.DrawableCompat
|
||||
import androidx.core.widget.TextViewCompat
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import io.legato.kazusa.R
|
||||
import io.legato.kazusa.utils.ColorUtils
|
||||
|
||||
/**
|
||||
* @author afollestad, plusCubed
|
||||
*/
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
object TintHelper {
|
||||
|
||||
@SuppressLint("PrivateResource")
|
||||
@ColorInt
|
||||
private fun getDefaultRippleColor(context: Context, useDarkRipple: Boolean): Int {
|
||||
// Light ripple is actually translucent black, and vice versa
|
||||
return ContextCompat.getColor(
|
||||
context, if (useDarkRipple)
|
||||
androidx.appcompat.R.color.ripple_material_light
|
||||
else
|
||||
androidx.appcompat.R.color.ripple_material_dark
|
||||
)
|
||||
}
|
||||
|
||||
private fun getDisabledColorStateList(
|
||||
@ColorInt normal: Int,
|
||||
@ColorInt disabled: Int
|
||||
): ColorStateList {
|
||||
return ColorStateList(
|
||||
arrayOf(
|
||||
intArrayOf(-android.R.attr.state_enabled),
|
||||
intArrayOf(android.R.attr.state_enabled)
|
||||
), intArrayOf(disabled, normal)
|
||||
)
|
||||
}
|
||||
|
||||
fun setTintSelector(view: View, @ColorInt color: Int, darker: Boolean, useDarkTheme: Boolean) {
|
||||
val isColorLight = ColorUtils.isColorLight(color)
|
||||
val disabled = ContextCompat.getColor(
|
||||
view.context,
|
||||
if (useDarkTheme) R.color.ate_button_disabled_dark else R.color.ate_button_disabled_light
|
||||
)
|
||||
val pressed = ColorUtils.shiftColor(color, if (darker) 0.9f else 1.1f)
|
||||
val activated = ColorUtils.shiftColor(color, if (darker) 1.1f else 0.9f)
|
||||
val rippleColor = getDefaultRippleColor(view.context, isColorLight)
|
||||
val textColor = ContextCompat.getColor(
|
||||
view.context,
|
||||
if (isColorLight) R.color.ate_primary_text_light else R.color.ate_primary_text_dark
|
||||
)
|
||||
|
||||
val sl: ColorStateList
|
||||
when (view) {
|
||||
is Button -> {
|
||||
sl = getDisabledColorStateList(color, disabled)
|
||||
if (view.getBackground() is RippleDrawable) {
|
||||
val rd = view.getBackground() as RippleDrawable
|
||||
rd.setColor(ColorStateList.valueOf(rippleColor))
|
||||
}
|
||||
// Disabled text color state for buttons, may get overridden later by ATE tags
|
||||
view.setTextColor(
|
||||
getDisabledColorStateList(
|
||||
textColor,
|
||||
ContextCompat.getColor(
|
||||
view.getContext(),
|
||||
if (useDarkTheme) R.color.ate_button_text_disabled_dark else R.color.ate_button_text_disabled_light
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
is FloatingActionButton -> {
|
||||
// FloatingActionButton doesn't support disabled state?
|
||||
sl = ColorStateList(
|
||||
arrayOf(
|
||||
intArrayOf(-android.R.attr.state_pressed),
|
||||
intArrayOf(android.R.attr.state_pressed)
|
||||
), intArrayOf(color, pressed)
|
||||
)
|
||||
|
||||
view.rippleColor = rippleColor
|
||||
view.backgroundTintList = sl
|
||||
if (view.drawable != null)
|
||||
view.setImageDrawable(createTintedDrawable(view.drawable, textColor))
|
||||
return
|
||||
}
|
||||
else -> {
|
||||
sl = ColorStateList(
|
||||
arrayOf(
|
||||
intArrayOf(-android.R.attr.state_enabled),
|
||||
intArrayOf(android.R.attr.state_enabled),
|
||||
intArrayOf(android.R.attr.state_enabled, android.R.attr.state_pressed),
|
||||
intArrayOf(android.R.attr.state_enabled, android.R.attr.state_activated),
|
||||
intArrayOf(android.R.attr.state_enabled, android.R.attr.state_checked)
|
||||
),
|
||||
intArrayOf(disabled, color, pressed, activated, activated)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
var drawable: Drawable? = view.background
|
||||
if (drawable != null) {
|
||||
drawable = createTintedDrawable(drawable, sl)
|
||||
ViewUtils.setBackgroundCompat(view, drawable)
|
||||
}
|
||||
|
||||
if (view is TextView && view !is Button) {
|
||||
view.setTextColor(
|
||||
getDisabledColorStateList(
|
||||
textColor,
|
||||
ContextCompat.getColor(
|
||||
view.getContext(),
|
||||
if (isColorLight) R.color.ate_text_disabled_light else R.color.ate_text_disabled_dark
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun setTintAuto(
|
||||
view: View,
|
||||
@ColorInt color: Int,
|
||||
isBackground: Boolean,
|
||||
isDark: Boolean
|
||||
) {
|
||||
var isBg = isBackground
|
||||
if (!isBg) {
|
||||
when (view) {
|
||||
is RadioButton -> setTint(view, color, isDark)
|
||||
is SeekBar -> setTint(view, color, isDark)
|
||||
is ProgressBar -> setTint(view, color)
|
||||
is AppCompatEditText -> setTint(view, color, isDark)
|
||||
is CheckBox -> setTint(view, color, isDark)
|
||||
is CheckedTextView -> setTint(view, color, isDark)
|
||||
is ImageView -> setTint(view, color)
|
||||
is Switch -> setTint(view, color, isDark)
|
||||
is SwitchCompat -> setTint(view, color, isDark)
|
||||
is SearchView -> {
|
||||
val iconIdS =
|
||||
intArrayOf(
|
||||
androidx.appcompat.R.id.search_button,
|
||||
androidx.appcompat.R.id.search_close_btn,
|
||||
androidx.appcompat.R.id.search_go_btn,
|
||||
androidx.appcompat.R.id.search_voice_btn,
|
||||
androidx.appcompat.R.id.search_mag_icon
|
||||
)
|
||||
for (iconId in iconIdS) {
|
||||
val icon = view.findViewById<ImageView>(iconId)
|
||||
if (icon != null) {
|
||||
setTint(icon, color)
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> isBg = true
|
||||
}
|
||||
if (!isBg && view.background is RippleDrawable) {
|
||||
// Ripples for the above views (e.g. when you tap and hold a switch or checkbox)
|
||||
val rd = view.background as RippleDrawable
|
||||
@SuppressLint("PrivateResource") val unchecked = ContextCompat.getColor(
|
||||
view.context,
|
||||
if (isDark) androidx.appcompat.R.color.ripple_material_dark else androidx.appcompat.R.color.ripple_material_light
|
||||
)
|
||||
val checked = ColorUtils.adjustAlpha(color, 0.4f)
|
||||
val sl = ColorStateList(
|
||||
arrayOf(
|
||||
intArrayOf(-android.R.attr.state_activated, -android.R.attr.state_checked),
|
||||
intArrayOf(android.R.attr.state_activated),
|
||||
intArrayOf(android.R.attr.state_checked)
|
||||
),
|
||||
intArrayOf(unchecked, checked, checked)
|
||||
)
|
||||
rd.setColor(sl)
|
||||
}
|
||||
}
|
||||
if (isBg) {
|
||||
// Need to tint the isBackground of a view
|
||||
if (view is FloatingActionButton || view is Button) {
|
||||
setTintSelector(view, color, false, isDark)
|
||||
} else if (view.background != null) {
|
||||
var drawable: Drawable? = view.background
|
||||
if (drawable != null) {
|
||||
drawable = createTintedDrawable(drawable, color)
|
||||
ViewUtils.setBackgroundCompat(view, drawable)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("PrivateResource")
|
||||
fun setTint(radioButton: RadioButton, @ColorInt color: Int, useDarker: Boolean) {
|
||||
val sl = ColorStateList(
|
||||
arrayOf(
|
||||
intArrayOf(-android.R.attr.state_enabled),
|
||||
intArrayOf(android.R.attr.state_enabled, -android.R.attr.state_checked),
|
||||
intArrayOf(android.R.attr.state_enabled, android.R.attr.state_checked)
|
||||
), intArrayOf(
|
||||
// Radio button includes own alpha for disabled state
|
||||
ColorUtils.stripAlpha(
|
||||
ContextCompat.getColor(
|
||||
radioButton.context,
|
||||
if (useDarker) R.color.ate_control_disabled_dark else R.color.ate_control_disabled_light
|
||||
)
|
||||
),
|
||||
ContextCompat.getColor(
|
||||
radioButton.context,
|
||||
if (useDarker) R.color.ate_control_normal_dark else R.color.ate_control_normal_light
|
||||
),
|
||||
color
|
||||
)
|
||||
)
|
||||
radioButton.buttonTintList = sl
|
||||
}
|
||||
|
||||
fun setTint(seekBar: SeekBar, @ColorInt color: Int, useDarker: Boolean) {
|
||||
val s1 = getDisabledColorStateList(
|
||||
color,
|
||||
ContextCompat.getColor(
|
||||
seekBar.context,
|
||||
if (useDarker) R.color.ate_control_disabled_dark else R.color.ate_control_disabled_light
|
||||
)
|
||||
)
|
||||
seekBar.thumbTintList = s1
|
||||
seekBar.progressTintList = s1
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
fun setTint(
|
||||
progressBar: ProgressBar, @ColorInt color: Int,
|
||||
skipIndeterminate: Boolean = false
|
||||
) {
|
||||
val sl = ColorStateList.valueOf(color)
|
||||
progressBar.progressTintList = sl
|
||||
progressBar.secondaryProgressTintList = sl
|
||||
if (!skipIndeterminate)
|
||||
progressBar.indeterminateTintList = sl
|
||||
}
|
||||
|
||||
|
||||
@SuppressLint("RestrictedApi")
|
||||
fun setTint(editText: AppCompatEditText, @ColorInt color: Int, useDarker: Boolean) {
|
||||
val editTextColorStateList = ColorStateList(
|
||||
arrayOf(
|
||||
intArrayOf(-android.R.attr.state_enabled),
|
||||
intArrayOf(
|
||||
android.R.attr.state_enabled,
|
||||
-android.R.attr.state_pressed,
|
||||
-android.R.attr.state_focused
|
||||
),
|
||||
intArrayOf()
|
||||
),
|
||||
intArrayOf(
|
||||
ContextCompat.getColor(
|
||||
editText.context,
|
||||
if (useDarker) R.color.ate_text_disabled_dark else R.color.ate_text_disabled_light
|
||||
),
|
||||
ContextCompat.getColor(
|
||||
editText.context,
|
||||
if (useDarker) R.color.ate_control_normal_dark else R.color.ate_control_normal_light
|
||||
),
|
||||
color
|
||||
)
|
||||
)
|
||||
editText.supportBackgroundTintList = editTextColorStateList
|
||||
setCursorTint(editText, color)
|
||||
}
|
||||
|
||||
@SuppressLint("PrivateResource")
|
||||
fun setTint(box: CheckBox, @ColorInt color: Int, useDarker: Boolean) {
|
||||
val sl = ColorStateList(
|
||||
arrayOf(
|
||||
intArrayOf(-android.R.attr.state_enabled),
|
||||
intArrayOf(android.R.attr.state_enabled, -android.R.attr.state_checked),
|
||||
intArrayOf(android.R.attr.state_enabled, android.R.attr.state_checked)
|
||||
),
|
||||
intArrayOf(
|
||||
ContextCompat.getColor(
|
||||
box.context,
|
||||
if (useDarker) R.color.ate_control_disabled_dark else R.color.ate_control_disabled_light
|
||||
),
|
||||
ContextCompat.getColor(
|
||||
box.context,
|
||||
if (useDarker) R.color.ate_control_normal_dark else R.color.ate_control_normal_light
|
||||
),
|
||||
color
|
||||
)
|
||||
)
|
||||
box.buttonTintList = sl
|
||||
}
|
||||
|
||||
@SuppressLint("PrivateResource")
|
||||
fun setTint(checkedTextView: CheckedTextView, @ColorInt color: Int, useDarker: Boolean) {
|
||||
val sl = ColorStateList(
|
||||
arrayOf(
|
||||
intArrayOf(-android.R.attr.state_enabled),
|
||||
intArrayOf(android.R.attr.state_enabled, -android.R.attr.state_checked),
|
||||
intArrayOf(android.R.attr.state_enabled, android.R.attr.state_checked)
|
||||
), intArrayOf(
|
||||
ContextCompat.getColor(
|
||||
checkedTextView.context,
|
||||
if (useDarker) R.color.ate_control_disabled_dark else R.color.ate_control_disabled_light
|
||||
),
|
||||
ContextCompat.getColor(
|
||||
checkedTextView.context,
|
||||
if (useDarker) R.color.ate_control_normal_dark else R.color.ate_control_normal_light
|
||||
),
|
||||
color
|
||||
)
|
||||
)
|
||||
checkedTextView.checkMarkTintList = sl
|
||||
TextViewCompat.setCompoundDrawableTintList(checkedTextView, sl)
|
||||
}
|
||||
|
||||
fun setTint(image: ImageView, @ColorInt color: Int) {
|
||||
image.setColorFilter(color, PorterDuff.Mode.SRC_ATOP)
|
||||
}
|
||||
|
||||
private fun modifySwitchDrawable(
|
||||
context: Context,
|
||||
from: Drawable,
|
||||
@ColorInt tint: Int,
|
||||
thumb: Boolean,
|
||||
compatSwitch: Boolean,
|
||||
useDarker: Boolean
|
||||
): Drawable? {
|
||||
var tint1 = tint
|
||||
if (useDarker) {
|
||||
tint1 = ColorUtils.shiftColor(tint1, 1.1f)
|
||||
}
|
||||
tint1 = ColorUtils.adjustAlpha(tint1, if (compatSwitch && !thumb) 0.5f else 1.0f)
|
||||
val disabled: Int
|
||||
var normal: Int
|
||||
if (thumb) {
|
||||
disabled = ContextCompat.getColor(
|
||||
context,
|
||||
if (useDarker) R.color.ate_switch_thumb_disabled_dark else R.color.ate_switch_thumb_disabled_light
|
||||
)
|
||||
normal = ContextCompat.getColor(
|
||||
context,
|
||||
if (useDarker) R.color.ate_switch_thumb_normal_dark else R.color.ate_switch_thumb_normal_light
|
||||
)
|
||||
} else {
|
||||
disabled = ContextCompat.getColor(
|
||||
context,
|
||||
if (useDarker) R.color.ate_switch_track_disabled_dark else R.color.ate_switch_track_disabled_light
|
||||
)
|
||||
normal = ContextCompat.getColor(
|
||||
context,
|
||||
if (useDarker) R.color.ate_switch_track_normal_dark else R.color.ate_switch_track_normal_light
|
||||
)
|
||||
}
|
||||
|
||||
// Stock switch includes its own alpha
|
||||
if (!compatSwitch) {
|
||||
normal = ColorUtils.stripAlpha(normal)
|
||||
}
|
||||
|
||||
val sl = ColorStateList(
|
||||
arrayOf(
|
||||
intArrayOf(-android.R.attr.state_enabled),
|
||||
intArrayOf(
|
||||
android.R.attr.state_enabled,
|
||||
-android.R.attr.state_activated,
|
||||
-android.R.attr.state_checked
|
||||
),
|
||||
intArrayOf(android.R.attr.state_enabled, android.R.attr.state_activated),
|
||||
intArrayOf(android.R.attr.state_enabled, android.R.attr.state_checked)
|
||||
),
|
||||
intArrayOf(disabled, normal, tint1, tint1)
|
||||
)
|
||||
return createTintedDrawable(from, sl)
|
||||
}
|
||||
|
||||
fun setTint(
|
||||
@SuppressLint("UseSwitchCompatOrMaterialCode") switchView: Switch,
|
||||
@ColorInt color: Int,
|
||||
useDarker: Boolean
|
||||
) {
|
||||
if (switchView.trackDrawable != null) {
|
||||
switchView.trackDrawable = modifySwitchDrawable(
|
||||
switchView.context,
|
||||
switchView.trackDrawable,
|
||||
color,
|
||||
thumb = false,
|
||||
compatSwitch = false,
|
||||
useDarker = useDarker
|
||||
)
|
||||
}
|
||||
if (switchView.thumbDrawable != null) {
|
||||
switchView.thumbDrawable = modifySwitchDrawable(
|
||||
switchView.context,
|
||||
switchView.thumbDrawable,
|
||||
color,
|
||||
thumb = true,
|
||||
compatSwitch = false,
|
||||
useDarker = useDarker
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun setTint(switchView: SwitchCompat, @ColorInt color: Int, useDarker: Boolean) {
|
||||
if (switchView.trackDrawable != null) {
|
||||
switchView.trackDrawable = modifySwitchDrawable(
|
||||
switchView.context,
|
||||
switchView.trackDrawable,
|
||||
color,
|
||||
thumb = false,
|
||||
compatSwitch = true,
|
||||
useDarker = useDarker
|
||||
)
|
||||
}
|
||||
if (switchView.thumbDrawable != null) {
|
||||
switchView.thumbDrawable = modifySwitchDrawable(
|
||||
switchView.context,
|
||||
switchView.thumbDrawable,
|
||||
color,
|
||||
thumb = true,
|
||||
compatSwitch = true,
|
||||
useDarker = useDarker
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// This returns a NEW Drawable because of the mutate() call. The mutate() call is necessary because Drawables with the same resource have shared states otherwise.
|
||||
@CheckResult
|
||||
fun createTintedDrawable(drawable: Drawable?, @ColorInt color: Int): Drawable? {
|
||||
var drawable1: Drawable? = drawable ?: return null
|
||||
drawable1 = DrawableCompat.wrap(drawable1!!.mutate())
|
||||
DrawableCompat.setTintMode(drawable1, PorterDuff.Mode.SRC_IN)
|
||||
DrawableCompat.setTint(drawable1, color)
|
||||
return drawable1
|
||||
}
|
||||
|
||||
// This returns a NEW Drawable because of the mutate() call. The mutate() call is necessary because Drawables with the same resource have shared states otherwise.
|
||||
@CheckResult
|
||||
fun createTintedDrawable(drawable: Drawable?, sl: ColorStateList): Drawable? {
|
||||
var drawable1: Drawable? = drawable ?: return null
|
||||
drawable1 = DrawableCompat.wrap(drawable1!!.mutate())
|
||||
DrawableCompat.setTintList(drawable1, sl)
|
||||
return drawable1
|
||||
}
|
||||
|
||||
@SuppressLint("DiscouragedPrivateApi", "SoonBlockedPrivateApi")
|
||||
fun setCursorTint(editText: EditText, @ColorInt color: Int) {
|
||||
try {
|
||||
val fCursorDrawableRes = TextView::class.java.getDeclaredField("mCursorDrawableRes")
|
||||
fCursorDrawableRes.isAccessible = true
|
||||
val mCursorDrawableRes = fCursorDrawableRes.getInt(editText)
|
||||
val fEditor = TextView::class.java.getDeclaredField("mEditor")
|
||||
fEditor.isAccessible = true
|
||||
val editor = fEditor.get(editText)
|
||||
val clazz = editor.javaClass
|
||||
val fCursorDrawable = clazz.getDeclaredField("mCursorDrawable")
|
||||
fCursorDrawable.isAccessible = true
|
||||
val drawables = arrayOfNulls<Drawable>(2)
|
||||
drawables[0] = ContextCompat.getDrawable(editText.context, mCursorDrawableRes)
|
||||
drawables[0] = createTintedDrawable(drawables[0], color)
|
||||
drawables[1] = ContextCompat.getDrawable(editText.context, mCursorDrawableRes)
|
||||
drawables[1] = createTintedDrawable(drawables[1], color)
|
||||
fCursorDrawable.set(editor, drawables)
|
||||
} catch (ignored: Exception) {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package io.legato.kazusa.lib.theme
|
||||
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.graphics.drawable.TransitionDrawable
|
||||
import android.view.View
|
||||
import android.view.ViewTreeObserver
|
||||
import androidx.annotation.ColorInt
|
||||
import io.legato.kazusa.utils.DrawableUtils
|
||||
|
||||
/**
|
||||
* @author Karim Abou Zeid (kabouzeid)
|
||||
*/
|
||||
@Suppress("unused")
|
||||
object ViewUtils {
|
||||
|
||||
fun removeOnGlobalLayoutListener(v: View, listener: ViewTreeObserver.OnGlobalLayoutListener) {
|
||||
v.viewTreeObserver.removeOnGlobalLayoutListener(listener)
|
||||
}
|
||||
|
||||
fun setBackgroundCompat(view: View, drawable: Drawable?) {
|
||||
view.background = drawable
|
||||
}
|
||||
|
||||
fun setBackgroundTransition(view: View, newDrawable: Drawable): TransitionDrawable {
|
||||
val transition = DrawableUtils.createTransitionDrawable(view.background, newDrawable)
|
||||
setBackgroundCompat(view, transition)
|
||||
return transition
|
||||
}
|
||||
|
||||
fun setBackgroundColorTransition(view: View, @ColorInt newColor: Int): TransitionDrawable {
|
||||
val oldColor = view.background
|
||||
|
||||
val start = oldColor ?: ColorDrawable(view.solidColor)
|
||||
val end = ColorDrawable(newColor)
|
||||
|
||||
val transition = DrawableUtils.createTransitionDrawable(start, end)
|
||||
|
||||
setBackgroundCompat(view, transition)
|
||||
|
||||
return transition
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package io.legato.kazusa.lib.theme.view
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.view.ViewCompat
|
||||
import com.google.android.material.bottomnavigation.BottomNavigationView
|
||||
import io.legato.kazusa.databinding.ViewNavigationBadgeBinding
|
||||
import io.legato.kazusa.help.config.AppConfig
|
||||
//import io.legado.app.lib.theme.bottomBackground
|
||||
//import io.legado.app.lib.theme.getSecondaryTextColor
|
||||
import io.legato.kazusa.ui.widget.text.BadgeView
|
||||
import androidx.core.graphics.drawable.toDrawable
|
||||
|
||||
class ThemeBottomNavigationVIew(context: Context, attrs: AttributeSet) :
|
||||
BottomNavigationView(context, attrs) {
|
||||
|
||||
init {
|
||||
// val bgColor = context.bottomBackground
|
||||
// setBackgroundColor(bgColor)
|
||||
// val textIsDark = ColorUtils.isColorLight(bgColor)
|
||||
// val textColor = context.getSecondaryTextColor(textIsDark)
|
||||
//
|
||||
// val colorStateList = Selector.colorBuild()
|
||||
// .setDefaultColor(textColor)
|
||||
// .setSelectedColor(ThemeStore.accentColor(context)).create()
|
||||
// itemIconTintList = colorStateList
|
||||
// itemTextColor = colorStateList
|
||||
|
||||
if (AppConfig.isEInkMode) {
|
||||
isItemHorizontalTranslationEnabled = false
|
||||
itemBackground = Color.TRANSPARENT.toDrawable()
|
||||
}
|
||||
|
||||
ViewCompat.setOnApplyWindowInsetsListener(this, null)
|
||||
}
|
||||
|
||||
fun addBadgeView(index: Int): BadgeView {
|
||||
//获取底部菜单view
|
||||
val menuView = getChildAt(0) as ViewGroup
|
||||
//获取第index个itemView
|
||||
val itemView = menuView.getChildAt(index) as ViewGroup
|
||||
val badgeBinding = ViewNavigationBadgeBinding.inflate(LayoutInflater.from(context))
|
||||
itemView.addView(badgeBinding.root)
|
||||
return badgeBinding.viewBadge
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package io.legato.kazusa.lib.theme.view
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import com.google.android.material.checkbox.MaterialCheckBox
|
||||
//import io.legado.app.lib.theme.accentColor
|
||||
|
||||
class ThemeCheckBox(context: Context, attrs: AttributeSet) : MaterialCheckBox(context, attrs) {
|
||||
|
||||
// init {
|
||||
// if (!isInEditMode) {
|
||||
// applyTint(context.accentColor)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package io.legato.kazusa.lib.theme.view
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import androidx.appcompat.widget.AppCompatEditText
|
||||
//import io.legado.app.lib.theme.accentColor
|
||||
|
||||
class ThemeEditText @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null
|
||||
) : AppCompatEditText(context, attrs) {
|
||||
|
||||
// init {
|
||||
// if (!isInEditMode) {
|
||||
// applyTint(context.accentColor)
|
||||
// }
|
||||
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
|
||||
// isLocalePreferredLineHeightForMinimumUsed = false
|
||||
// }
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package io.legato.kazusa.lib.theme.view
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.widget.ProgressBar
|
||||
//import io.legado.app.lib.theme.accentColor
|
||||
|
||||
class ThemeProgressBar(context: Context, attrs: AttributeSet) : ProgressBar(context, attrs) {
|
||||
|
||||
// init {
|
||||
// if (!isInEditMode) {
|
||||
// applyTint(context.accentColor)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package io.legato.kazusa.lib.theme.view
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import com.google.android.material.radiobutton.MaterialRadioButton
|
||||
//import io.legado.app.lib.theme.accentColor
|
||||
|
||||
class ThemeRadioButton(context: Context, attrs: AttributeSet) :
|
||||
MaterialRadioButton(context, attrs) {
|
||||
|
||||
// init {
|
||||
// if (!isInEditMode) {
|
||||
// applyTint(context.accentColor)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package io.legato.kazusa.lib.theme.view
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import androidx.appcompat.widget.TooltipCompat
|
||||
import com.google.android.material.radiobutton.MaterialRadioButton
|
||||
import io.legato.kazusa.R
|
||||
//import io.legado.app.lib.theme.accentColor
|
||||
//import io.legado.app.lib.theme.bottomBackground
|
||||
//import io.legado.app.lib.theme.getPrimaryTextColor
|
||||
|
||||
class ThemeRadioNoButton(context: Context, attrs: AttributeSet) :
|
||||
MaterialRadioButton(context, attrs) {
|
||||
|
||||
private val isBottomBackground: Boolean
|
||||
|
||||
init {
|
||||
val typedArray = context.obtainStyledAttributes(attrs, R.styleable.ThemeRadioNoButton)
|
||||
isBottomBackground =
|
||||
typedArray.getBoolean(R.styleable.ThemeRadioNoButton_isBottomBackground, false)
|
||||
typedArray.recycle()
|
||||
initTheme()
|
||||
TooltipCompat.setTooltipText(this, text)
|
||||
}
|
||||
|
||||
private fun initTheme() {
|
||||
// when {
|
||||
// isInEditMode -> Unit
|
||||
// isBottomBackground -> {
|
||||
// val accentColor = context.accentColor
|
||||
// val isLight = ColorUtils.isColorLight(context.bottomBackground)
|
||||
// val textColor = context.getPrimaryTextColor(isLight)
|
||||
// val checkedTextColor = if (ColorUtils.isColorLight(accentColor)) {
|
||||
// Color.BLACK
|
||||
// } else {
|
||||
// Color.WHITE
|
||||
// }
|
||||
// background = Selector.shapeBuild()
|
||||
// .setCornerRadius(2.dpToPx())
|
||||
// .setStrokeWidth(2.dpToPx())
|
||||
// .setCheckedBgColor(accentColor)
|
||||
// .setCheckedStrokeColor(accentColor)
|
||||
// .setDefaultStrokeColor(textColor)
|
||||
// .create()
|
||||
// setTextColor(
|
||||
// Selector.colorBuild()
|
||||
// .setDefaultColor(textColor)
|
||||
// .setCheckedColor(checkedTextColor)
|
||||
// .create()
|
||||
// )
|
||||
// }
|
||||
// else -> {
|
||||
// val accentColor = context.accentColor
|
||||
// val defaultTextColor = context.getCompatColor(R.color.primaryText)
|
||||
// val checkedTextColor = if (ColorUtils.isColorLight(accentColor)) {
|
||||
// Color.BLACK
|
||||
// } else {
|
||||
// Color.WHITE
|
||||
// }
|
||||
// background = Selector.shapeBuild()
|
||||
// .setCornerRadius(2.dpToPx())
|
||||
// .setStrokeWidth(2.dpToPx())
|
||||
// .setCheckedBgColor(accentColor)
|
||||
// .setCheckedStrokeColor(accentColor)
|
||||
// .setDefaultStrokeColor(defaultTextColor)
|
||||
// .create()
|
||||
// setTextColor(
|
||||
// Selector.colorBuild()
|
||||
// .setDefaultColor(defaultTextColor)
|
||||
// .setCheckedColor(checkedTextColor)
|
||||
// .create()
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package io.legato.kazusa.lib.theme.view
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import com.google.android.material.slider.Slider
|
||||
//import io.legado.app.lib.theme.accentColor
|
||||
|
||||
/**
|
||||
* @author Aidan Follestad (afollestad)
|
||||
*/
|
||||
class ThemeSlider(context: Context, attrs: AttributeSet) : Slider(context, attrs) {
|
||||
|
||||
// init {
|
||||
// if (!isInEditMode) {
|
||||
// applyTint(context.accentColor)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package io.legato.kazusa.lib.theme.view
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import com.google.android.material.materialswitch.MaterialSwitch
|
||||
//import io.legado.app.lib.theme.accentColor
|
||||
|
||||
/**
|
||||
* @author Aidan Follestad (afollestad)
|
||||
*/
|
||||
class ThemeSwitch(context: Context, attrs: AttributeSet) : MaterialSwitch(context, attrs) {
|
||||
|
||||
// init {
|
||||
// if (!isInEditMode) {
|
||||
// applyTint(context.accentColor)
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user