From d20488b6bc8df329ed59a0c24d67218957a543cb Mon Sep 17 00:00:00 2001 From: Ivan Zakharov <79067180651@ya.ru> Date: Wed, 11 Mar 2020 16:05:26 +0300 Subject: [PATCH 1/4] Add russian localization --- library/src/main/res/values-ru/strings.xml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 library/src/main/res/values-ru/strings.xml diff --git a/library/src/main/res/values-ru/strings.xml b/library/src/main/res/values-ru/strings.xml new file mode 100644 index 0000000..cbac421 --- /dev/null +++ b/library/src/main/res/values-ru/strings.xml @@ -0,0 +1,19 @@ + + Выбор темы + + Темы + Выбор предустановленной темы + + Основной цвет + Наиболее используемый в приложении. + + Цветовой акцент + Акцент, которым выделяются части интерфейса. + + Цвет фона + Цвет подложки у содержимого приложения + Внешний вид + + Цвет панели навигации + Применить основной цвет к панели навигации + From 5376620d9013ef21e423ea3c0dc5ee62f6bff321 Mon Sep 17 00:00:00 2001 From: Ivan Zakharov <79067180651@ya.ru> Date: Wed, 11 Mar 2020 16:07:55 +0300 Subject: [PATCH 2/4] Fix applying color filter on low api FATAL EXCEPTION: main java.lang.NoClassDefFoundError: android.graphics.BlendModeColorFilter --- .../java/com/jaredrummler/cyanea/Extensions.kt | 14 ++++++++++++++ .../jaredrummler/cyanea/tinting/EdgeEffectTint.kt | 5 ++--- .../com/jaredrummler/cyanea/tinting/MenuTint.kt | 7 ++++--- .../com/jaredrummler/cyanea/tinting/WidgetTint.kt | 5 +++-- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/library/src/main/java/com/jaredrummler/cyanea/Extensions.kt b/library/src/main/java/com/jaredrummler/cyanea/Extensions.kt index b8aadd0..1e49496 100644 --- a/library/src/main/java/com/jaredrummler/cyanea/Extensions.kt +++ b/library/src/main/java/com/jaredrummler/cyanea/Extensions.kt @@ -17,10 +17,15 @@ package com.jaredrummler.cyanea import android.content.res.Resources +import android.graphics.BlendMode +import android.graphics.BlendModeColorFilter +import android.graphics.PorterDuff +import android.graphics.drawable.Drawable import android.os.Build import android.util.TypedValue import com.jaredrummler.cyanea.utils.Reflection + internal fun Resources.getKey(id: Int, resolveRefs: Boolean = true) = getValue(id, resolveRefs).let { it.assetCookie.toLong() shl 32 or it.data.toLong() } @@ -34,3 +39,12 @@ internal fun Resources.getValue(id: Int, resolveRefs: Boolean = true) = TypedVal id, value, resolveRefs) } } + +internal fun Drawable.setColorFilterCompat(color: Int, mode: PorterDuff.Mode) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + colorFilter = BlendModeColorFilter(color, BlendMode.valueOf(mode.name)) + } else { + @Suppress("DEPRECATION") + setColorFilter(color, mode) + } +} diff --git a/library/src/main/java/com/jaredrummler/cyanea/tinting/EdgeEffectTint.kt b/library/src/main/java/com/jaredrummler/cyanea/tinting/EdgeEffectTint.kt index 8be7b91..c19b5d8 100644 --- a/library/src/main/java/com/jaredrummler/cyanea/tinting/EdgeEffectTint.kt +++ b/library/src/main/java/com/jaredrummler/cyanea/tinting/EdgeEffectTint.kt @@ -17,8 +17,6 @@ package com.jaredrummler.cyanea.tinting import android.app.Activity -import android.graphics.BlendMode.SRC_IN -import android.graphics.BlendModeColorFilter import android.graphics.PorterDuff import android.graphics.drawable.Drawable import android.os.Build @@ -34,6 +32,7 @@ import androidx.core.widget.EdgeEffectCompat import androidx.core.widget.NestedScrollView import androidx.viewpager.widget.ViewPager import com.jaredrummler.cyanea.Cyanea +import com.jaredrummler.cyanea.setColorFilterCompat import com.jaredrummler.cyanea.utils.Reflection /** @@ -86,7 +85,7 @@ class EdgeEffectTint(private val view: ViewGroup) { } for (name in arrayOf("mEdge", "mGlow")) { val drawable = Reflection.getFieldValue(edgeEffect, name) - drawable?.colorFilter = BlendModeColorFilter(color, SRC_IN) + drawable?.setColorFilterCompat(color, PorterDuff.Mode.SRC_IN) drawable?.callback = null // free up any references } } catch (e: Exception) { diff --git a/library/src/main/java/com/jaredrummler/cyanea/tinting/MenuTint.kt b/library/src/main/java/com/jaredrummler/cyanea/tinting/MenuTint.kt index cb15aae..70c36f0 100644 --- a/library/src/main/java/com/jaredrummler/cyanea/tinting/MenuTint.kt +++ b/library/src/main/java/com/jaredrummler/cyanea/tinting/MenuTint.kt @@ -36,6 +36,7 @@ import androidx.annotation.DrawableRes import androidx.appcompat.view.menu.MenuItemImpl import androidx.appcompat.widget.ActionMenuView import com.jaredrummler.cyanea.Cyanea +import com.jaredrummler.cyanea.setColorFilterCompat import com.jaredrummler.cyanea.utils.Reflection /** @@ -164,14 +165,14 @@ class MenuTint( actionBar.navigationIcon?.let { icon -> menuIconColor?.let { color -> val navigationIcon = icon.mutate() - navigationIcon.colorFilter = BlendModeColorFilter(color, BlendMode.SRC_IN) + navigationIcon.setColorFilterCompat(color, PorterDuff.Mode.SRC_IN) } } } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && actionBar is Toolbar) { actionBar.navigationIcon?.let { icon -> menuIconColor?.let { color -> val navigationIcon = icon.mutate() - navigationIcon.colorFilter = BlendModeColorFilter(color, BlendMode.SRC_IN) + navigationIcon.setColorFilterCompat(color, PorterDuff.Mode.SRC_IN) } } } @@ -206,7 +207,7 @@ class MenuTint( fun colorMenuItem(menuItem: MenuItem, color: Int?, alpha: Int? = null) { menuItem.icon?.let { icon -> val drawable = icon.mutate() - color?.let { drawable.colorFilter = BlendModeColorFilter(color, SRC_IN) } + color?.let { drawable.setColorFilterCompat(color, PorterDuff.Mode.SRC_IN) } alpha?.let { drawable.alpha = it } menuItem.icon = drawable } diff --git a/library/src/main/java/com/jaredrummler/cyanea/tinting/WidgetTint.kt b/library/src/main/java/com/jaredrummler/cyanea/tinting/WidgetTint.kt index 4ae65a3..fd20497 100644 --- a/library/src/main/java/com/jaredrummler/cyanea/tinting/WidgetTint.kt +++ b/library/src/main/java/com/jaredrummler/cyanea/tinting/WidgetTint.kt @@ -28,6 +28,7 @@ import android.widget.TextView import androidx.annotation.ColorInt import androidx.core.content.ContextCompat import com.jaredrummler.cyanea.Cyanea +import com.jaredrummler.cyanea.setColorFilterCompat import com.jaredrummler.cyanea.utils.Reflection /** @@ -58,7 +59,7 @@ class WidgetTint private constructor() { ?.setColorFilter(color, PorterDuff.Mode.SRC_ATOP) } else { Reflection.getFieldValue(scroller, "mThumbDrawable") - ?.colorFilter = BlendModeColorFilter(color, SRC_ATOP) + ?.setColorFilterCompat(color, PorterDuff.Mode.SRC_ATOP) } } catch (e: Exception) { Cyanea.log(TAG, "Error tinting the fast scroll thumb", e) @@ -79,7 +80,7 @@ class WidgetTint private constructor() { Reflection.getField(editor, "mCursorDrawable")?.let { fCursorDrawable -> val cursorDrawableRes = fCursorDrawableRes.getInt(textView) ContextCompat.getDrawable(textView.context, cursorDrawableRes)?.let { drawable -> - drawable.colorFilter = BlendModeColorFilter(color, SRC_IN) + drawable.setColorFilterCompat(color, PorterDuff.Mode.SRC_IN) val drawables = arrayOf(drawable, drawable) fCursorDrawable.set(editor, drawables) } From 3fa18624653767cbe6a7c1e670527d4e4fd85685 Mon Sep 17 00:00:00 2001 From: Ivan Zakharov <79067180651@ya.ru> Date: Wed, 11 Mar 2020 16:56:40 +0300 Subject: [PATCH 3/4] Fixed applying edge color to some viewGroups and recyclerview --- .../cyanea/prefs/CyaneaSettingsFragment.kt | 8 +++ .../cyanea/tinting/EdgeEffectTint.kt | 70 ++++++++++++++----- 2 files changed, 61 insertions(+), 17 deletions(-) diff --git a/library/src/main/java/com/jaredrummler/cyanea/prefs/CyaneaSettingsFragment.kt b/library/src/main/java/com/jaredrummler/cyanea/prefs/CyaneaSettingsFragment.kt index faa2ac0..e039b23 100644 --- a/library/src/main/java/com/jaredrummler/cyanea/prefs/CyaneaSettingsFragment.kt +++ b/library/src/main/java/com/jaredrummler/cyanea/prefs/CyaneaSettingsFragment.kt @@ -22,6 +22,7 @@ import android.os.Build import android.os.Build.VERSION import android.os.Build.VERSION_CODES import android.os.Bundle +import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.annotation.XmlRes @@ -39,6 +40,7 @@ import com.jaredrummler.android.colorpicker.ColorPreferenceCompat import com.jaredrummler.cyanea.Cyanea import com.jaredrummler.cyanea.R import com.jaredrummler.cyanea.app.BaseCyaneaActivity +import com.jaredrummler.cyanea.tinting.EdgeEffectTint import com.jaredrummler.cyanea.tinting.SystemBarTint import com.jaredrummler.cyanea.utils.ColorUtils @@ -165,6 +167,12 @@ open class CyaneaSettingsFragment : PreferenceFragmentCompat(), OnPreferenceChan } } + override fun onCreateRecyclerView(inflater: LayoutInflater?, parent: ViewGroup?, savedInstanceState: Bundle?): RecyclerView { + return super.onCreateRecyclerView(inflater, parent, savedInstanceState).apply { + EdgeEffectTint.setEdgeGlowColor(this, cyanea.primary) + } + } + private fun setupNavBarPref() { ColorUtils.isDarkColor(cyanea.primary, 0.75).let { isDarkEnough -> prefColorNavBar.isEnabled = isDarkEnough || VERSION.SDK_INT >= VERSION_CODES.O diff --git a/library/src/main/java/com/jaredrummler/cyanea/tinting/EdgeEffectTint.kt b/library/src/main/java/com/jaredrummler/cyanea/tinting/EdgeEffectTint.kt index c19b5d8..ab057e7 100644 --- a/library/src/main/java/com/jaredrummler/cyanea/tinting/EdgeEffectTint.kt +++ b/library/src/main/java/com/jaredrummler/cyanea/tinting/EdgeEffectTint.kt @@ -30,6 +30,7 @@ import android.widget.ScrollView import androidx.annotation.ColorInt import androidx.core.widget.EdgeEffectCompat import androidx.core.widget.NestedScrollView +import androidx.recyclerview.widget.RecyclerView import androidx.viewpager.widget.ViewPager import com.jaredrummler.cyanea.Cyanea import com.jaredrummler.cyanea.setColorFilterCompat @@ -104,6 +105,7 @@ class EdgeEffectTint(private val view: ViewGroup) { * * [NestedScrollView] * * [ViewPager] * * [WebView] + * * [RecyclerView] * * @param view The view to set the edge color * @param color The color value @@ -117,6 +119,7 @@ class EdgeEffectTint(private val view: ViewGroup) { is NestedScrollView -> setEdgeGlowColor(view, color) is ViewPager -> setEdgeGlowColor(view, color) is WebView -> setEdgeGlowColor(view, color) + is RecyclerView -> setEdgeGlowColor(view, color) else -> return false } return true @@ -154,13 +157,18 @@ class EdgeEffectTint(private val view: ViewGroup) { * @param color The color value */ private fun setEdgeGlowColor(listView: AbsListView, @ColorInt color: Int) { - try { - for (name in arrayOf("mEdgeGlowTop", "mEdgeGlowBottom")) { - Reflection.getFieldValue(listView, name)?.let { edgeEffect -> - setEdgeEffectColor(edgeEffect, color) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + listView.topEdgeEffectColor = color + listView.bottomEdgeEffectColor = color + } else { + try { + for (name in arrayOf("mEdgeGlowTop", "mEdgeGlowBottom")) { + Reflection.getFieldValue(listView, name)?.let { edgeEffect -> + setEdgeEffectColor(edgeEffect, color) + } } + } catch (ignored: Exception) { } - } catch (ignored: Exception) { } } @@ -171,13 +179,18 @@ class EdgeEffectTint(private val view: ViewGroup) { * @param color The color value */ private fun setEdgeGlowColor(hsv: HorizontalScrollView, @ColorInt color: Int) { - try { - for (name in arrayOf("mEdgeGlowLeft", "mEdgeGlowRight")) { - val edgeEffect = Reflection.getFieldValue(hsv, name) - edgeEffect?.let { setEdgeEffectColor(it, color) } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + hsv.leftEdgeEffectColor = color + hsv.rightEdgeEffectColor = color + } else { + try { + for (name in arrayOf("mEdgeGlowLeft", "mEdgeGlowRight")) { + val edgeEffect = Reflection.getFieldValue(hsv, name) + edgeEffect?.let { setEdgeEffectColor(it, color) } + } + } catch (e: Exception) { + Cyanea.log(TAG, "Error setting edge glow color on HorizontalScrollView", e) } - } catch (e: Exception) { - Cyanea.log(TAG, "Error setting edge glow color on HorizontalScrollView", e) } } @@ -188,13 +201,18 @@ class EdgeEffectTint(private val view: ViewGroup) { * @param color The color value */ private fun setEdgeGlowColor(scrollView: ScrollView, color: Int) { - try { - for (name in arrayOf("mEdgeGlowTop", "mEdgeGlowBottom")) { - val edgeEffect = Reflection.getFieldValue(scrollView, name) - edgeEffect?.let { setEdgeEffectColor(it, color) } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + scrollView.topEdgeEffectColor = color + scrollView.bottomEdgeEffectColor = color + } else { + try { + for (name in arrayOf("mEdgeGlowTop", "mEdgeGlowBottom")) { + val edgeEffect = Reflection.getFieldValue(scrollView, name) + edgeEffect?.let { setEdgeEffectColor(it, color) } + } + } catch (e: Exception) { + Cyanea.log(TAG, "Error setting edge glow color on ScrollView", e) } - } catch (e: Exception) { - Cyanea.log(TAG, "Error setting edge glow color on ScrollView", e) } } @@ -244,5 +262,23 @@ class EdgeEffectTint(private val view: ViewGroup) { Cyanea.log(TAG, "Error setting edge glow color on WebView", e) } } + + /** + * Set the edge-effect color on a [RecyclerView]. + * + * @param recyclerView + * the RecyclerView + * @param color + * the color value + */ + private fun setEdgeGlowColor(recyclerView: RecyclerView, color: Int) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + recyclerView.edgeEffectFactory = object : RecyclerView.EdgeEffectFactory() { + override fun createEdgeEffect(view: RecyclerView, direction: Int): EdgeEffect { + return EdgeEffect(view.context).apply { this.color = color } + } + } + } + } } } From 5e3f14e289ee10732d1be204822da833d5f4e62c Mon Sep 17 00:00:00 2001 From: Ivan Zakharov <79067180651@ya.ru> Date: Tue, 17 Mar 2020 14:47:53 +0300 Subject: [PATCH 4/4] fixed applying colors to actionBar --- demo-main/src/main/res/layout/activity_drawer.xml | 1 + demo-simple-java/src/main/res/layout/activity_main.xml | 1 + library/src/main/java/com/jaredrummler/cyanea/Constants.kt | 2 +- library/src/main/java/com/jaredrummler/cyanea/Cyanea.kt | 4 ++-- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/demo-main/src/main/res/layout/activity_drawer.xml b/demo-main/src/main/res/layout/activity_drawer.xml index 0449ca0..bdb2547 100644 --- a/demo-main/src/main/res/layout/activity_drawer.xml +++ b/demo-main/src/main/res/layout/activity_drawer.xml @@ -26,6 +26,7 @@ android:theme="?actionBarTheme" app:popupTheme="?popupTheme" app:title="@string/drawer_layout" + app:titleTextColor="?menuIconColor" tools:ignore="UnusedAttribute" /> diff --git a/demo-simple-java/src/main/res/layout/activity_main.xml b/demo-simple-java/src/main/res/layout/activity_main.xml index f854cb7..79cb800 100644 --- a/demo-simple-java/src/main/res/layout/activity_main.xml +++ b/demo-simple-java/src/main/res/layout/activity_main.xml @@ -20,6 +20,7 @@ android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:popupTheme="?popupTheme" + app:titleTextColor="?menuIconColor" /> diff --git a/library/src/main/java/com/jaredrummler/cyanea/Constants.kt b/library/src/main/java/com/jaredrummler/cyanea/Constants.kt index f45d68c..443201b 100644 --- a/library/src/main/java/com/jaredrummler/cyanea/Constants.kt +++ b/library/src/main/java/com/jaredrummler/cyanea/Constants.kt @@ -18,7 +18,7 @@ package com.jaredrummler.cyanea internal object Constants { internal const val NONE_TIMESTAMP = 0L - internal const val LIGHT_ACTIONBAR_LUMINANCE_FACTOR = 0.75 + internal const val LIGHT_ACTIONBAR_LUMINANCE_FACTOR = 0.6 } internal object PrefKeys { diff --git a/library/src/main/java/com/jaredrummler/cyanea/Cyanea.kt b/library/src/main/java/com/jaredrummler/cyanea/Cyanea.kt index de8bfa6..2f1db21 100644 --- a/library/src/main/java/com/jaredrummler/cyanea/Cyanea.kt +++ b/library/src/main/java/com/jaredrummler/cyanea/Cyanea.kt @@ -171,7 +171,7 @@ class Cyanea private constructor(private val prefs: SharedPreferences) { /** True if the [baseTheme] is [LIGHT] */ val isLight get() = baseTheme == LIGHT /** True if the [primary] color is a dark color */ - val isActionBarDark get() = ColorUtils.isDarkColor(primary, 0.75) + val isActionBarDark get() = ColorUtils.isDarkColor(primary, LIGHT_ACTIONBAR_LUMINANCE_FACTOR) /** True if the [primary] color is a light color */ val isActionBarLight get() = !isActionBarDark /** True if the theme has been modified at least once */ @@ -553,7 +553,7 @@ class Cyanea private constructor(private val prefs: SharedPreferences) { fun background(@ColorInt color: Int): Editor { val lighter = ColorUtils.lighter(color, DEFAULT_LIGHTER_FACTOR) val darker = ColorUtils.darker(color, DEFAULT_DARKER_FACTOR) - val isDarkColor = ColorUtils.isDarkColor(color, LIGHT_ACTIONBAR_LUMINANCE_FACTOR) + val isDarkColor = ColorUtils.isDarkColor(color) if (isDarkColor) { baseTheme(DARK) backgroundDark(color)