diff options
Diffstat (limited to 'library/src/main/kotlin/ca/allanwang/kau/utils/ColorUtils.kt')
-rw-r--r-- | library/src/main/kotlin/ca/allanwang/kau/utils/ColorUtils.kt | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/library/src/main/kotlin/ca/allanwang/kau/utils/ColorUtils.kt b/library/src/main/kotlin/ca/allanwang/kau/utils/ColorUtils.kt new file mode 100644 index 0000000..8e396c7 --- /dev/null +++ b/library/src/main/kotlin/ca/allanwang/kau/utils/ColorUtils.kt @@ -0,0 +1,183 @@ +package ca.allanwang.kau.utils + +import android.content.Context +import android.content.res.ColorStateList +import android.graphics.Color +import android.graphics.PorterDuff +import android.graphics.drawable.Drawable +import android.os.Build +import android.support.annotation.ColorInt +import android.support.annotation.IntRange +import android.support.v4.content.ContextCompat +import android.support.v4.graphics.drawable.DrawableCompat +import android.support.v7.widget.AppCompatEditText +import android.widget.* +import com.afollestad.materialdialogs.R + +/** + * Created by Allan Wang on 2017-06-08. + */ +fun Int.isColorDark(): Boolean + = (0.299 * Color.red(this) + 0.587 * Color.green(this) + 0.114 * Color.blue(this)) / 255.0 < 0.5 + +fun Int.toHexString(withAlpha: Boolean = false, withHexPrefix:Boolean = true): String { + val hex = if (withAlpha) String.format("#%08X", this) + else String.format("#%06X", 0xFFFFFF and this) + return if (withHexPrefix) hex else hex.substring(1) +} + +fun Int.isColorVisibleOn(@ColorInt color: Int, @IntRange(from = 0L, to = 255L) delta: Int = 8, + @IntRange(from = 0L, to = 255L) minAlpha: Int = 50): Boolean = + if (Color.alpha(this) < minAlpha) false + else (Math.abs(Color.red(this) - Color.red(color)) < delta + && Math.abs(Color.green(this) - Color.green(color)) < delta + && Math.abs(Color.blue(this) - Color.blue(color)) < delta) + + +@ColorInt +fun Context.getDisabledColor(): Int { + val primaryColor = resolveColor(android.R.attr.textColorPrimary) + val disabledColor = if (primaryColor.isColorDark()) Color.BLACK else Color.WHITE + return disabledColor.adjustAlpha(0.3f) +} + +@ColorInt +fun Int.adjustAlpha(factor: Float): Int { + val alpha = Math.round(Color.alpha(this) * factor) + return Color.argb(alpha, Color.red(this), Color.green(this), Color.blue(this)) +} + +@Throws(IllegalArgumentException::class) +fun String.toColor(): Int { + val toParse: String + if (startsWith("#") && length == 4) + toParse = "#${this[1]}${this[1]}${this[2]}${this[2]}${this[3]}${this[3]}" + else + toParse = this + return Color.parseColor(toParse) +} + +//Get ColorStateList +fun Context.colorStateList(@ColorInt color: Int): ColorStateList { + val disabledColor = getDisabledColor() + return ColorStateList(arrayOf(intArrayOf(android.R.attr.state_enabled, -android.R.attr.state_checked), + intArrayOf(android.R.attr.state_enabled, android.R.attr.state_checked), + intArrayOf(-android.R.attr.state_enabled, -android.R.attr.state_checked), + intArrayOf(-android.R.attr.state_enabled, android.R.attr.state_checked)), + intArrayOf(this.resolveColor(R.attr.colorControlNormal), color, disabledColor, disabledColor)) +} + +/* + * Tint Helpers + * Kotlin tint bindings that start with 'tint' so it doesn't conflict with existing methods + * Largely based on MDTintHelper + * https://github.com/afollestad/material-dialogs/blob/master/core/src/main/java/com/afollestad/materialdialogs/internal/MDTintHelper.java + */ +fun RadioButton.tint(colors: ColorStateList) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + buttonTintList = colors + } else { + val radioDrawable = context.drawable(R.drawable.abc_btn_radio_material) + val d = DrawableCompat.wrap(radioDrawable) + DrawableCompat.setTintList(d, colors) + buttonDrawable = d + } +} + +fun RadioButton.tint(@ColorInt color: Int) = tint(context.colorStateList(color)) + +fun CheckBox.tint(colors: ColorStateList) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + buttonTintList = colors + } else { + val checkDrawable = context.drawable(R.drawable.abc_btn_check_material) + val drawable = DrawableCompat.wrap(checkDrawable) + DrawableCompat.setTintList(drawable, colors) + buttonDrawable = drawable + } +} + +fun CheckBox.tint(@ColorInt color: Int) = tint(context.colorStateList(color)) + +fun SeekBar.tint(@ColorInt color: Int) { + val s1 = ColorStateList.valueOf(color) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + thumbTintList = s1 + progressTintList = s1 + } else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.GINGERBREAD_MR1) { + val progressDrawable = DrawableCompat.wrap(progressDrawable) + this.progressDrawable = progressDrawable + DrawableCompat.setTintList(progressDrawable, s1) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + val thumbDrawable = DrawableCompat.wrap(thumb) + DrawableCompat.setTintList(thumbDrawable, s1) + thumb = thumbDrawable + } + } else { + val mode: PorterDuff.Mode = if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) + PorterDuff.Mode.MULTIPLY else PorterDuff.Mode.SRC_IN + indeterminateDrawable?.setColorFilter(color, mode) + progressDrawable?.setColorFilter(color, mode) + } +} + +fun ProgressBar.tint(@ColorInt color: Int, skipIndeterminate: Boolean = false) { + val sl = ColorStateList.valueOf(color) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + progressTintList = sl + secondaryProgressTintList = sl + if (!skipIndeterminate) indeterminateTintList = sl + } else { + val mode: PorterDuff.Mode = if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) + PorterDuff.Mode.MULTIPLY else PorterDuff.Mode.SRC_IN + indeterminateDrawable?.setColorFilter(color, mode) + progressDrawable?.setColorFilter(color, mode) + } +} + +fun Context.textColorStateList(@ColorInt color: Int): ColorStateList { + val states = arrayOf( + intArrayOf(-android.R.attr.state_enabled), + intArrayOf(-android.R.attr.state_pressed, -android.R.attr.state_focused), + intArrayOf() + ) + val colors = intArrayOf( + resolveColor(R.attr.colorControlNormal), + resolveColor(R.attr.colorControlNormal), + color + ) + return ColorStateList(states, colors) +} + +fun EditText.tint(@ColorInt color: Int) { + val editTextColorStateList = context.textColorStateList(color) + if (this is AppCompatEditText) { + supportBackgroundTintList = editTextColorStateList + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + backgroundTintList = editTextColorStateList + } + tintCursor(color) +} + +fun EditText.tintCursor(@ColorInt color: Int) { + try { + val fCursorDrawableRes = TextView::class.java.getDeclaredField("mCursorDrawableRes") + fCursorDrawableRes.isAccessible = true + val mCursorDrawableRes = fCursorDrawableRes.getInt(this) + val fEditor = TextView::class.java.getDeclaredField("mEditor") + fEditor.isAccessible = true + val editor = fEditor.get(this) + val clazz = editor.javaClass + val fCursorDrawable = clazz.getDeclaredField("mCursorDrawable") + fCursorDrawable.isAccessible = true + val drawables: Array<Drawable> = Array(2, { + val drawable = ContextCompat.getDrawable(context, mCursorDrawableRes) + drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN) + drawable + }) + fCursorDrawable.set(editor, drawables) + } catch (e: Exception) { + e.printStackTrace() + } + +}
\ No newline at end of file |