commit
6b2ef8fb76
@ -0,0 +1,117 @@ |
|||||||
|
package io.legado.app.lib.theme; |
||||||
|
|
||||||
|
import android.annotation.SuppressLint; |
||||||
|
import android.app.Activity; |
||||||
|
import android.app.ActivityManager; |
||||||
|
import android.content.Context; |
||||||
|
import android.content.res.ColorStateList; |
||||||
|
import android.os.Build; |
||||||
|
import android.view.View; |
||||||
|
import androidx.annotation.ColorInt; |
||||||
|
import androidx.annotation.NonNull; |
||||||
|
import androidx.appcompat.app.AlertDialog; |
||||||
|
|
||||||
|
import static android.view.View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Karim Abou Zeid (kabouzeid) |
||||||
|
*/ |
||||||
|
public final class ATH { |
||||||
|
|
||||||
|
@SuppressLint("CommitPrefEdits") |
||||||
|
public static boolean didThemeValuesChange(@NonNull Context context, long since) { |
||||||
|
return ThemeStore.isConfigured(context) && ThemeStore.prefs(context).getLong(ThemeStore.VALUES_CHANGED, -1) > since; |
||||||
|
} |
||||||
|
|
||||||
|
public static void setStatusbarColorAuto(Activity activity) { |
||||||
|
setStatusbarColor(activity, ThemeStore.statusBarColor(activity)); |
||||||
|
} |
||||||
|
|
||||||
|
public static void setStatusbarColor(Activity activity, int color) { |
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { |
||||||
|
activity.getWindow().setStatusBarColor(color); |
||||||
|
setLightStatusbarAuto(activity, color); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void setLightStatusbarAuto(Activity activity, int bgColor) { |
||||||
|
setLightStatusbar(activity, ColorUtil.isColorLight(bgColor)); |
||||||
|
} |
||||||
|
|
||||||
|
public static void setLightStatusbar(Activity activity, boolean enabled) { |
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { |
||||||
|
final View decorView = activity.getWindow().getDecorView(); |
||||||
|
final int systemUiVisibility = decorView.getSystemUiVisibility(); |
||||||
|
if (enabled) { |
||||||
|
decorView.setSystemUiVisibility(systemUiVisibility | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); |
||||||
|
} else { |
||||||
|
decorView.setSystemUiVisibility(systemUiVisibility & ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void setLightNavigationbar(Activity activity, boolean enabled) { |
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { |
||||||
|
final View decorView = activity.getWindow().getDecorView(); |
||||||
|
int systemUiVisibility = decorView.getSystemUiVisibility(); |
||||||
|
if (enabled) { |
||||||
|
systemUiVisibility |= SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; |
||||||
|
} else { |
||||||
|
systemUiVisibility &= ~SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; |
||||||
|
} |
||||||
|
decorView.setSystemUiVisibility(systemUiVisibility); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void setLightNavigationbarAuto(Activity activity, int bgColor) { |
||||||
|
setLightNavigationbar(activity, ColorUtil.isColorLight(bgColor)); |
||||||
|
} |
||||||
|
|
||||||
|
public static void setNavigationbarColorAuto(Activity activity) { |
||||||
|
setNavigationbarColor(activity, ThemeStore.navigationBarColor(activity)); |
||||||
|
} |
||||||
|
|
||||||
|
public static void setNavigationbarColor(Activity activity, int color) { |
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { |
||||||
|
activity.getWindow().setNavigationBarColor(color); |
||||||
|
setLightNavigationbarAuto(activity, color); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void setTaskDescriptionColorAuto(@NonNull Activity activity) { |
||||||
|
setTaskDescriptionColor(activity, ThemeStore.primaryColor(activity)); |
||||||
|
} |
||||||
|
|
||||||
|
public static void setTaskDescriptionColor(@NonNull Activity activity, @ColorInt int color) { |
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { |
||||||
|
// Task description requires fully opaque color
|
||||||
|
color = ColorUtil.stripAlpha(color); |
||||||
|
// Sets color of entry in the system recents page
|
||||||
|
activity.setTaskDescription(new ActivityManager.TaskDescription((String) activity.getTitle(), null, color)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void setTint(@NonNull View view, @ColorInt int color) { |
||||||
|
TintHelper.setTintAuto(view, color, false); |
||||||
|
} |
||||||
|
|
||||||
|
public static void setBackgroundTint(@NonNull View view, @ColorInt int color) { |
||||||
|
TintHelper.setTintAuto(view, color, true); |
||||||
|
} |
||||||
|
|
||||||
|
public static void setAlertDialogTint(@NonNull AlertDialog dialog) { |
||||||
|
ColorStateList colorStateList = Selector.colorBuild() |
||||||
|
.setDefaultColor(ThemeStore.accentColor(dialog.getContext())) |
||||||
|
.setPressedColor(ColorUtil.darkenColor(ThemeStore.accentColor(dialog.getContext()))) |
||||||
|
.create(); |
||||||
|
if (dialog.getButton(androidx.appcompat.app.AlertDialog.BUTTON_NEGATIVE) != null) { |
||||||
|
dialog.getButton(androidx.appcompat.app.AlertDialog.BUTTON_NEGATIVE).setTextColor(colorStateList); |
||||||
|
} |
||||||
|
if (dialog.getButton(androidx.appcompat.app.AlertDialog.BUTTON_POSITIVE) != null) { |
||||||
|
dialog.getButton(androidx.appcompat.app.AlertDialog.BUTTON_POSITIVE).setTextColor(colorStateList); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private ATH() { |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,31 @@ |
|||||||
|
package io.legado.app.lib.theme; |
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.content.res.TypedArray; |
||||||
|
import androidx.annotation.AttrRes; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Aidan Follestad (afollestad) |
||||||
|
*/ |
||||||
|
public final class ATHUtil { |
||||||
|
|
||||||
|
public static boolean isWindowBackgroundDark(Context context) { |
||||||
|
return !ColorUtil.isColorLight(ATHUtil.resolveColor(context, android.R.attr.windowBackground)); |
||||||
|
} |
||||||
|
|
||||||
|
public static int resolveColor(Context context, @AttrRes int attr) { |
||||||
|
return resolveColor(context, attr, 0); |
||||||
|
} |
||||||
|
|
||||||
|
public static int resolveColor(Context context, @AttrRes int attr, int fallback) { |
||||||
|
TypedArray a = context.getTheme().obtainStyledAttributes(new int[]{attr}); |
||||||
|
try { |
||||||
|
return a.getColor(0, fallback); |
||||||
|
} finally { |
||||||
|
a.recycle(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private ATHUtil() { |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,80 @@ |
|||||||
|
package io.legado.app.lib.theme; |
||||||
|
|
||||||
|
import android.graphics.Color; |
||||||
|
import androidx.annotation.ColorInt; |
||||||
|
import androidx.annotation.FloatRange; |
||||||
|
|
||||||
|
@SuppressWarnings({"unused", "WeakerAccess"}) |
||||||
|
public class ColorUtil { |
||||||
|
|
||||||
|
public static String intToString(int intColor) { |
||||||
|
return String.format("#%06X", 0xFFFFFF & intColor); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public static int stripAlpha(@ColorInt int color) { |
||||||
|
return 0xff000000 | color; |
||||||
|
} |
||||||
|
|
||||||
|
@ColorInt |
||||||
|
public static int shiftColor(@ColorInt int color, @FloatRange(from = 0.0f, to = 2.0f) float by) { |
||||||
|
if (by == 1f) return color; |
||||||
|
int alpha = Color.alpha(color); |
||||||
|
float[] hsv = new float[3]; |
||||||
|
Color.colorToHSV(color, hsv); |
||||||
|
hsv[2] *= by; // value component
|
||||||
|
return (alpha << 24) + (0x00ffffff & Color.HSVToColor(hsv)); |
||||||
|
} |
||||||
|
|
||||||
|
@ColorInt |
||||||
|
public static int darkenColor(@ColorInt int color) { |
||||||
|
return shiftColor(color, 0.9f); |
||||||
|
} |
||||||
|
|
||||||
|
@ColorInt |
||||||
|
public static int lightenColor(@ColorInt int color) { |
||||||
|
return shiftColor(color, 1.1f); |
||||||
|
} |
||||||
|
|
||||||
|
public static boolean isColorLight(@ColorInt int color) { |
||||||
|
final double darkness = 1 - (0.299 * Color.red(color) + 0.587 * Color.green(color) + 0.114 * Color.blue(color)) / 255; |
||||||
|
return darkness < 0.4; |
||||||
|
} |
||||||
|
|
||||||
|
@ColorInt |
||||||
|
public static int invertColor(@ColorInt int color) { |
||||||
|
final int r = 255 - Color.red(color); |
||||||
|
final int g = 255 - Color.green(color); |
||||||
|
final int b = 255 - Color.blue(color); |
||||||
|
return Color.argb(Color.alpha(color), r, g, b); |
||||||
|
} |
||||||
|
|
||||||
|
@ColorInt |
||||||
|
public static int adjustAlpha(@ColorInt int color, @FloatRange(from = 0.0, to = 1.0) float factor) { |
||||||
|
int alpha = Math.round(Color.alpha(color) * factor); |
||||||
|
int red = Color.red(color); |
||||||
|
int green = Color.green(color); |
||||||
|
int blue = Color.blue(color); |
||||||
|
return Color.argb(alpha, red, green, blue); |
||||||
|
} |
||||||
|
|
||||||
|
@ColorInt |
||||||
|
public static int withAlpha(@ColorInt int baseColor, @FloatRange(from = 0.0, to = 1.0) float alpha) { |
||||||
|
int a = Math.min(255, Math.max(0, (int) (alpha * 255))) << 24; |
||||||
|
int rgb = 0x00ffffff & baseColor; |
||||||
|
return a + rgb; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Taken from CollapsingToolbarLayout's CollapsingTextHelper class. |
||||||
|
*/ |
||||||
|
public static int blendColors(int color1, int color2, @FloatRange(from = 0.0, to = 1.0) float ratio) { |
||||||
|
final float inverseRatio = 1f - ratio; |
||||||
|
float a = (Color.alpha(color1) * inverseRatio) + (Color.alpha(color2) * ratio); |
||||||
|
float r = (Color.red(color1) * inverseRatio) + (Color.red(color2) * ratio); |
||||||
|
float g = (Color.green(color1) * inverseRatio) + (Color.green(color2) * ratio); |
||||||
|
float b = (Color.blue(color1) * inverseRatio) + (Color.blue(color2) * ratio); |
||||||
|
return Color.argb((int) a, (int) r, (int) g, (int) b); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,28 @@ |
|||||||
|
package io.legado.app.lib.theme; |
||||||
|
|
||||||
|
import android.graphics.drawable.ColorDrawable; |
||||||
|
import android.graphics.drawable.Drawable; |
||||||
|
import android.graphics.drawable.TransitionDrawable; |
||||||
|
import androidx.annotation.ColorInt; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Karim Abou Zeid (kabouzeid) |
||||||
|
*/ |
||||||
|
public final class DrawableUtil { |
||||||
|
|
||||||
|
public static TransitionDrawable createTransitionDrawable(@ColorInt int startColor, @ColorInt int endColor) { |
||||||
|
return createTransitionDrawable(new ColorDrawable(startColor), new ColorDrawable(endColor)); |
||||||
|
} |
||||||
|
|
||||||
|
public static TransitionDrawable createTransitionDrawable(Drawable start, Drawable end) { |
||||||
|
final Drawable[] drawables = new Drawable[2]; |
||||||
|
|
||||||
|
drawables[0] = start; |
||||||
|
drawables[1] = end; |
||||||
|
|
||||||
|
return new TransitionDrawable(drawables); |
||||||
|
} |
||||||
|
|
||||||
|
private DrawableUtil() { |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,52 @@ |
|||||||
|
package io.legado.app.lib.theme; |
||||||
|
|
||||||
|
import android.annotation.SuppressLint; |
||||||
|
import android.content.Context; |
||||||
|
import androidx.annotation.ColorInt; |
||||||
|
import androidx.core.content.ContextCompat; |
||||||
|
import io.legado.app.R; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Karim Abou Zeid (kabouzeid) |
||||||
|
*/ |
||||||
|
public final class MaterialValueHelper { |
||||||
|
|
||||||
|
@SuppressLint("PrivateResource") |
||||||
|
@ColorInt |
||||||
|
public static int getPrimaryTextColor(final Context context, boolean dark) { |
||||||
|
if (dark) { |
||||||
|
return ContextCompat.getColor(context, R.color.primary_text_default_material_light); |
||||||
|
} |
||||||
|
return ContextCompat.getColor(context, R.color.primary_text_default_material_dark); |
||||||
|
} |
||||||
|
|
||||||
|
@SuppressLint("PrivateResource") |
||||||
|
@ColorInt |
||||||
|
public static int getSecondaryTextColor(final Context context, boolean dark) { |
||||||
|
if (dark) { |
||||||
|
return ContextCompat.getColor(context, R.color.secondary_text_default_material_light); |
||||||
|
} |
||||||
|
return ContextCompat.getColor(context, R.color.secondary_text_default_material_dark); |
||||||
|
} |
||||||
|
|
||||||
|
@SuppressLint("PrivateResource") |
||||||
|
@ColorInt |
||||||
|
public static int getPrimaryDisabledTextColor(final Context context, boolean dark) { |
||||||
|
if (dark) { |
||||||
|
return ContextCompat.getColor(context, R.color.primary_text_disabled_material_light); |
||||||
|
} |
||||||
|
return ContextCompat.getColor(context, R.color.primary_text_disabled_material_dark); |
||||||
|
} |
||||||
|
|
||||||
|
@SuppressLint("PrivateResource") |
||||||
|
@ColorInt |
||||||
|
public static int getSecondaryDisabledTextColor(final Context context, boolean dark) { |
||||||
|
if (dark) { |
||||||
|
return ContextCompat.getColor(context, R.color.secondary_text_disabled_material_light); |
||||||
|
} |
||||||
|
return ContextCompat.getColor(context, R.color.secondary_text_disabled_material_dark); |
||||||
|
} |
||||||
|
|
||||||
|
private MaterialValueHelper() { |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,55 @@ |
|||||||
|
package io.legado.app.lib.theme; |
||||||
|
|
||||||
|
import android.content.res.ColorStateList; |
||||||
|
import androidx.annotation.ColorInt; |
||||||
|
import androidx.annotation.NonNull; |
||||||
|
import com.google.android.material.internal.NavigationMenuView; |
||||||
|
import com.google.android.material.navigation.NavigationView; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Karim Abou Zeid (kabouzeid) |
||||||
|
*/ |
||||||
|
public final class NavigationViewUtil { |
||||||
|
|
||||||
|
public static void setItemIconColors(@NonNull NavigationView navigationView, @ColorInt int normalColor, @ColorInt int selectedColor) { |
||||||
|
final ColorStateList iconSl = new ColorStateList( |
||||||
|
new int[][]{ |
||||||
|
new int[]{-android.R.attr.state_checked}, |
||||||
|
new int[]{android.R.attr.state_checked} |
||||||
|
}, |
||||||
|
new int[]{ |
||||||
|
normalColor, |
||||||
|
selectedColor |
||||||
|
}); |
||||||
|
navigationView.setItemIconTintList(iconSl); |
||||||
|
} |
||||||
|
|
||||||
|
public static void setItemTextColors(@NonNull NavigationView navigationView, @ColorInt int normalColor, @ColorInt int selectedColor) { |
||||||
|
final ColorStateList textSl = new ColorStateList( |
||||||
|
new int[][]{ |
||||||
|
new int[]{-android.R.attr.state_checked}, |
||||||
|
new int[]{android.R.attr.state_checked} |
||||||
|
}, |
||||||
|
new int[]{ |
||||||
|
normalColor, |
||||||
|
selectedColor |
||||||
|
}); |
||||||
|
navigationView.setItemTextColor(textSl); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 去掉navigationView的滚动条 |
||||||
|
* @param navigationView NavigationView |
||||||
|
*/ |
||||||
|
public static void disableScrollbar(NavigationView navigationView) { |
||||||
|
if (navigationView != null) { |
||||||
|
NavigationMenuView navigationMenuView = (NavigationMenuView) navigationView.getChildAt(0); |
||||||
|
if (navigationMenuView != null) { |
||||||
|
navigationMenuView.setVerticalScrollBarEnabled(false); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private NavigationViewUtil() { |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,430 @@ |
|||||||
|
package io.legado.app.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; |
||||||
|
|
||||||
|
public class Selector { |
||||||
|
public static ShapeSelector shapeBuild() { |
||||||
|
return new ShapeSelector(); |
||||||
|
} |
||||||
|
|
||||||
|
public static ColorSelector colorBuild() { |
||||||
|
return new ColorSelector(); |
||||||
|
} |
||||||
|
|
||||||
|
public static DrawableSelector drawableBuild() { |
||||||
|
return new DrawableSelector(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 形状ShapeSelector |
||||||
|
* |
||||||
|
* @author hjy |
||||||
|
* created at 2017/12/11 22:26 |
||||||
|
*/ |
||||||
|
public static final class ShapeSelector { |
||||||
|
@IntDef({GradientDrawable.RECTANGLE, GradientDrawable.OVAL, |
||||||
|
GradientDrawable.LINE, GradientDrawable.RING}) |
||||||
|
private @interface Shape { |
||||||
|
} |
||||||
|
|
||||||
|
private int mShape; //the shape of background
|
||||||
|
private int mDefaultBgColor; //default background color
|
||||||
|
private int mDisabledBgColor; //state_enabled = false
|
||||||
|
private int mPressedBgColor; //state_pressed = true
|
||||||
|
private int mSelectedBgColor; //state_selected = true
|
||||||
|
private int mFocusedBgColor; //state_focused = true
|
||||||
|
private int mCheckedBgColor; //state_checked = true
|
||||||
|
private int mStrokeWidth; //stroke width in pixel
|
||||||
|
private int mDefaultStrokeColor; //default stroke color
|
||||||
|
private int mDisabledStrokeColor; //state_enabled = false
|
||||||
|
private int mPressedStrokeColor; //state_pressed = true
|
||||||
|
private int mSelectedStrokeColor; //state_selected = true
|
||||||
|
private int mFocusedStrokeColor; //state_focused = true
|
||||||
|
private int mCheckedStrokeColor; //state_checked = true
|
||||||
|
private int mCornerRadius; //corner radius
|
||||||
|
|
||||||
|
private boolean hasSetDisabledBgColor = false; |
||||||
|
private boolean hasSetPressedBgColor = false; |
||||||
|
private boolean hasSetSelectedBgColor = false; |
||||||
|
private boolean hasSetFocusedBgColor = false; |
||||||
|
private boolean hasSetCheckedBgColor = false; |
||||||
|
|
||||||
|
private boolean hasSetDisabledStrokeColor = false; |
||||||
|
private boolean hasSetPressedStrokeColor = false; |
||||||
|
private boolean hasSetSelectedStrokeColor = false; |
||||||
|
private boolean hasSetFocusedStrokeColor = false; |
||||||
|
private boolean hasSetCheckedStrokeColor = false; |
||||||
|
|
||||||
|
public ShapeSelector() { |
||||||
|
//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; |
||||||
|
} |
||||||
|
|
||||||
|
public ShapeSelector setShape(@Shape int shape) { |
||||||
|
mShape = shape; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public ShapeSelector setDefaultBgColor(@ColorInt int color) { |
||||||
|
mDefaultBgColor = color; |
||||||
|
if (!hasSetDisabledBgColor) |
||||||
|
mDisabledBgColor = color; |
||||||
|
if (!hasSetPressedBgColor) |
||||||
|
mPressedBgColor = color; |
||||||
|
if (!hasSetSelectedBgColor) |
||||||
|
mSelectedBgColor = color; |
||||||
|
if (!hasSetFocusedBgColor) |
||||||
|
mFocusedBgColor = color; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public ShapeSelector setDisabledBgColor(@ColorInt int color) { |
||||||
|
mDisabledBgColor = color; |
||||||
|
hasSetDisabledBgColor = true; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public ShapeSelector setPressedBgColor(@ColorInt int color) { |
||||||
|
mPressedBgColor = color; |
||||||
|
hasSetPressedBgColor = true; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public ShapeSelector setSelectedBgColor(@ColorInt int color) { |
||||||
|
mSelectedBgColor = color; |
||||||
|
hasSetSelectedBgColor = true; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public ShapeSelector setFocusedBgColor(@ColorInt int color) { |
||||||
|
mFocusedBgColor = color; |
||||||
|
hasSetPressedBgColor = true; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public ShapeSelector setCheckedBgColor(@ColorInt int color) { |
||||||
|
mCheckedBgColor = color; |
||||||
|
hasSetCheckedBgColor = true; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public ShapeSelector setStrokeWidth(@Dimension int width) { |
||||||
|
mStrokeWidth = width; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public ShapeSelector setDefaultStrokeColor(@ColorInt int color) { |
||||||
|
mDefaultStrokeColor = color; |
||||||
|
if (!hasSetDisabledStrokeColor) |
||||||
|
mDisabledStrokeColor = color; |
||||||
|
if (!hasSetPressedStrokeColor) |
||||||
|
mPressedStrokeColor = color; |
||||||
|
if (!hasSetSelectedStrokeColor) |
||||||
|
mSelectedStrokeColor = color; |
||||||
|
if (!hasSetFocusedStrokeColor) |
||||||
|
mFocusedStrokeColor = color; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public ShapeSelector setDisabledStrokeColor(@ColorInt int color) { |
||||||
|
mDisabledStrokeColor = color; |
||||||
|
hasSetDisabledStrokeColor = true; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public ShapeSelector setPressedStrokeColor(@ColorInt int color) { |
||||||
|
mPressedStrokeColor = color; |
||||||
|
hasSetPressedStrokeColor = true; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public ShapeSelector setSelectedStrokeColor(@ColorInt int color) { |
||||||
|
mSelectedStrokeColor = color; |
||||||
|
hasSetSelectedStrokeColor = true; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public ShapeSelector setCheckedStrokeColor(@ColorInt int color) { |
||||||
|
mCheckedStrokeColor = color; |
||||||
|
hasSetCheckedStrokeColor = true; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public ShapeSelector setFocusedStrokeColor(@ColorInt int color) { |
||||||
|
mFocusedStrokeColor = color; |
||||||
|
hasSetFocusedStrokeColor = true; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public ShapeSelector setCornerRadius(@Dimension int radius) { |
||||||
|
mCornerRadius = radius; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public StateListDrawable create() { |
||||||
|
StateListDrawable selector = new StateListDrawable(); |
||||||
|
|
||||||
|
//enabled = false
|
||||||
|
if (hasSetDisabledBgColor || hasSetDisabledStrokeColor) { |
||||||
|
GradientDrawable disabledShape = getItemShape(mShape, mCornerRadius, |
||||||
|
mDisabledBgColor, mStrokeWidth, mDisabledStrokeColor); |
||||||
|
selector.addState(new int[]{-android.R.attr.state_enabled}, disabledShape); |
||||||
|
} |
||||||
|
|
||||||
|
//pressed = true
|
||||||
|
if (hasSetPressedBgColor || hasSetPressedStrokeColor) { |
||||||
|
GradientDrawable pressedShape = getItemShape(mShape, mCornerRadius, |
||||||
|
mPressedBgColor, mStrokeWidth, mPressedStrokeColor); |
||||||
|
selector.addState(new int[]{android.R.attr.state_pressed}, pressedShape); |
||||||
|
} |
||||||
|
|
||||||
|
//selected = true
|
||||||
|
if (hasSetSelectedBgColor || hasSetSelectedStrokeColor) { |
||||||
|
GradientDrawable selectedShape = getItemShape(mShape, mCornerRadius, |
||||||
|
mSelectedBgColor, mStrokeWidth, mSelectedStrokeColor); |
||||||
|
selector.addState(new int[]{android.R.attr.state_selected}, selectedShape); |
||||||
|
} |
||||||
|
|
||||||
|
//focused = true
|
||||||
|
if (hasSetFocusedBgColor || hasSetFocusedStrokeColor) { |
||||||
|
GradientDrawable focusedShape = getItemShape(mShape, mCornerRadius, |
||||||
|
mFocusedBgColor, mStrokeWidth, mFocusedStrokeColor); |
||||||
|
selector.addState(new int[]{android.R.attr.state_focused}, focusedShape); |
||||||
|
} |
||||||
|
|
||||||
|
//checked = true
|
||||||
|
if (hasSetCheckedBgColor || hasSetCheckedStrokeColor) { |
||||||
|
GradientDrawable checkedShape = getItemShape(mShape, mCornerRadius, |
||||||
|
mCheckedBgColor, mStrokeWidth, mCheckedStrokeColor); |
||||||
|
selector.addState(new int[]{android.R.attr.state_checked}, checkedShape); |
||||||
|
} |
||||||
|
|
||||||
|
//default
|
||||||
|
GradientDrawable defaultShape = getItemShape(mShape, mCornerRadius, |
||||||
|
mDefaultBgColor, mStrokeWidth, mDefaultStrokeColor); |
||||||
|
selector.addState(new int[]{}, defaultShape); |
||||||
|
|
||||||
|
return selector; |
||||||
|
} |
||||||
|
|
||||||
|
private GradientDrawable getItemShape(int shape, int cornerRadius, |
||||||
|
int solidColor, int strokeWidth, int strokeColor) { |
||||||
|
GradientDrawable drawable = new GradientDrawable(); |
||||||
|
drawable.setShape(shape); |
||||||
|
drawable.setStroke(strokeWidth, strokeColor); |
||||||
|
drawable.setCornerRadius(cornerRadius); |
||||||
|
drawable.setColor(solidColor); |
||||||
|
return drawable; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 资源DrawableSelector |
||||||
|
* |
||||||
|
* @author hjy |
||||||
|
* created at 2017/12/11 22:34 |
||||||
|
*/ |
||||||
|
public static final class DrawableSelector { |
||||||
|
|
||||||
|
private Drawable mDefaultDrawable; |
||||||
|
private Drawable mDisabledDrawable; |
||||||
|
private Drawable mPressedDrawable; |
||||||
|
private Drawable mSelectedDrawable; |
||||||
|
private Drawable mFocusedDrawable; |
||||||
|
|
||||||
|
private boolean hasSetDisabledDrawable = false; |
||||||
|
private boolean hasSetPressedDrawable = false; |
||||||
|
private boolean hasSetSelectedDrawable = false; |
||||||
|
private boolean hasSetFocusedDrawable = false; |
||||||
|
|
||||||
|
private DrawableSelector() { |
||||||
|
mDefaultDrawable = new ColorDrawable(Color.TRANSPARENT); |
||||||
|
} |
||||||
|
|
||||||
|
public DrawableSelector setDefaultDrawable(Drawable drawable) { |
||||||
|
mDefaultDrawable = drawable; |
||||||
|
if (!hasSetDisabledDrawable) |
||||||
|
mDisabledDrawable = drawable; |
||||||
|
if (!hasSetPressedDrawable) |
||||||
|
mPressedDrawable = drawable; |
||||||
|
if (!hasSetSelectedDrawable) |
||||||
|
mSelectedDrawable = drawable; |
||||||
|
if (!hasSetFocusedDrawable) |
||||||
|
mFocusedDrawable = drawable; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public DrawableSelector setDisabledDrawable(Drawable drawable) { |
||||||
|
mDisabledDrawable = drawable; |
||||||
|
hasSetDisabledDrawable = true; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public DrawableSelector setPressedDrawable(Drawable drawable) { |
||||||
|
mPressedDrawable = drawable; |
||||||
|
hasSetPressedDrawable = true; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public DrawableSelector setSelectedDrawable(Drawable drawable) { |
||||||
|
mSelectedDrawable = drawable; |
||||||
|
hasSetSelectedDrawable = true; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public DrawableSelector setFocusedDrawable(Drawable drawable) { |
||||||
|
mFocusedDrawable = drawable; |
||||||
|
hasSetFocusedDrawable = true; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public StateListDrawable create() { |
||||||
|
StateListDrawable selector = new StateListDrawable(); |
||||||
|
if (hasSetDisabledDrawable) |
||||||
|
selector.addState(new int[]{-android.R.attr.state_enabled}, mDisabledDrawable); |
||||||
|
if (hasSetPressedDrawable) |
||||||
|
selector.addState(new int[]{android.R.attr.state_pressed}, mPressedDrawable); |
||||||
|
if (hasSetSelectedDrawable) |
||||||
|
selector.addState(new int[]{android.R.attr.state_selected}, mSelectedDrawable); |
||||||
|
if (hasSetFocusedDrawable) |
||||||
|
selector.addState(new int[]{android.R.attr.state_focused}, mFocusedDrawable); |
||||||
|
selector.addState(new int[]{}, mDefaultDrawable); |
||||||
|
return selector; |
||||||
|
} |
||||||
|
|
||||||
|
public DrawableSelector setDefaultDrawable(Context context, @DrawableRes int drawableRes) { |
||||||
|
return setDefaultDrawable(ContextCompat.getDrawable(context, drawableRes)); |
||||||
|
} |
||||||
|
|
||||||
|
public DrawableSelector setDisabledDrawable(Context context, @DrawableRes int drawableRes) { |
||||||
|
return setDisabledDrawable(ContextCompat.getDrawable(context, drawableRes)); |
||||||
|
} |
||||||
|
|
||||||
|
public DrawableSelector setPressedDrawable(Context context, @DrawableRes int drawableRes) { |
||||||
|
return setPressedDrawable(ContextCompat.getDrawable(context, drawableRes)); |
||||||
|
} |
||||||
|
|
||||||
|
public DrawableSelector setSelectedDrawable(Context context, @DrawableRes int drawableRes) { |
||||||
|
return setSelectedDrawable(ContextCompat.getDrawable(context, drawableRes)); |
||||||
|
} |
||||||
|
|
||||||
|
public DrawableSelector setFocusedDrawable(Context context, @DrawableRes int drawableRes) { |
||||||
|
return setFocusedDrawable(ContextCompat.getDrawable(context, drawableRes)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 颜色ColorSelector |
||||||
|
* |
||||||
|
* @author hjy |
||||||
|
* created at 2017/12/11 22:26 |
||||||
|
*/ |
||||||
|
public static final class ColorSelector { |
||||||
|
|
||||||
|
private int mDefaultColor; |
||||||
|
private int mDisabledColor; |
||||||
|
private int mPressedColor; |
||||||
|
private int mSelectedColor; |
||||||
|
private int mFocusedColor; |
||||||
|
private int mCheckedColor; |
||||||
|
|
||||||
|
private boolean hasSetDisabledColor = false; |
||||||
|
private boolean hasSetPressedColor = false; |
||||||
|
private boolean hasSetSelectedColor = false; |
||||||
|
private boolean hasSetFocusedColor = false; |
||||||
|
private boolean hasSetCheckedColor = false; |
||||||
|
|
||||||
|
private ColorSelector() { |
||||||
|
mDefaultColor = Color.BLACK; |
||||||
|
mDisabledColor = Color.GRAY; |
||||||
|
mPressedColor = Color.BLACK; |
||||||
|
mSelectedColor = Color.BLACK; |
||||||
|
mFocusedColor = Color.BLACK; |
||||||
|
} |
||||||
|
|
||||||
|
public ColorSelector setDefaultColor(@ColorInt int color) { |
||||||
|
mDefaultColor = color; |
||||||
|
if (!hasSetDisabledColor) |
||||||
|
mDisabledColor = color; |
||||||
|
if (!hasSetPressedColor) |
||||||
|
mPressedColor = color; |
||||||
|
if (!hasSetSelectedColor) |
||||||
|
mSelectedColor = color; |
||||||
|
if (!hasSetFocusedColor) |
||||||
|
mFocusedColor = color; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public ColorSelector setDisabledColor(@ColorInt int color) { |
||||||
|
mDisabledColor = color; |
||||||
|
hasSetDisabledColor = true; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public ColorSelector setPressedColor(@ColorInt int color) { |
||||||
|
mPressedColor = color; |
||||||
|
hasSetPressedColor = true; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public ColorSelector setSelectedColor(@ColorInt int color) { |
||||||
|
mSelectedColor = color; |
||||||
|
hasSetSelectedColor = true; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public ColorSelector setFocusedColor(@ColorInt int color) { |
||||||
|
mFocusedColor = color; |
||||||
|
hasSetFocusedColor = true; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public ColorSelector setCheckedColor(@ColorInt int color) { |
||||||
|
mCheckedColor = color; |
||||||
|
hasSetCheckedColor = true; |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public ColorStateList create() { |
||||||
|
int[] colors = new int[]{ |
||||||
|
hasSetDisabledColor ? mDisabledColor : mDefaultColor, |
||||||
|
hasSetPressedColor ? mPressedColor : mDefaultColor, |
||||||
|
hasSetSelectedColor ? mSelectedColor : mDefaultColor, |
||||||
|
hasSetFocusedColor ? mFocusedColor : mDefaultColor, |
||||||
|
hasSetCheckedColor ? mCheckedColor : mDefaultColor, |
||||||
|
mDefaultColor |
||||||
|
}; |
||||||
|
int[][] states = new int[6][]; |
||||||
|
states[0] = new int[]{-android.R.attr.state_enabled}; |
||||||
|
states[1] = new int[]{android.R.attr.state_pressed}; |
||||||
|
states[2] = new int[]{android.R.attr.state_selected}; |
||||||
|
states[3] = new int[]{android.R.attr.state_focused}; |
||||||
|
states[4] = new int[]{android.R.attr.state_checked}; |
||||||
|
states[5] = new int[]{}; |
||||||
|
return new ColorStateList(states, colors); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,318 @@ |
|||||||
|
package io.legado.app.lib.theme; |
||||||
|
|
||||||
|
import android.annotation.SuppressLint; |
||||||
|
import android.content.Context; |
||||||
|
import android.content.SharedPreferences; |
||||||
|
import android.graphics.Color; |
||||||
|
import androidx.annotation.*; |
||||||
|
import androidx.core.content.ContextCompat; |
||||||
|
import io.legado.app.R; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Aidan Follestad (afollestad), Karim Abou Zeid (kabouzeid) |
||||||
|
*/ |
||||||
|
public final class ThemeStore implements ThemeStorePrefKeys, ThemeStoreInterface { |
||||||
|
|
||||||
|
private final Context mContext; |
||||||
|
private final SharedPreferences.Editor mEditor; |
||||||
|
|
||||||
|
public static ThemeStore editTheme(@NonNull Context context) { |
||||||
|
return new ThemeStore(context); |
||||||
|
} |
||||||
|
|
||||||
|
@SuppressLint("CommitPrefEdits") |
||||||
|
private ThemeStore(@NonNull Context context) { |
||||||
|
mContext = context; |
||||||
|
mEditor = prefs(context).edit(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public ThemeStore primaryColor(@ColorInt int color) { |
||||||
|
mEditor.putInt(KEY_PRIMARY_COLOR, color); |
||||||
|
if (autoGeneratePrimaryDark(mContext)) |
||||||
|
primaryColorDark(ColorUtil.darkenColor(color)); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ThemeStore primaryColorRes(@ColorRes int colorRes) { |
||||||
|
return primaryColor(ContextCompat.getColor(mContext, colorRes)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ThemeStore primaryColorAttr(@AttrRes int colorAttr) { |
||||||
|
return primaryColor(ATHUtil.resolveColor(mContext, colorAttr)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ThemeStore primaryColorDark(@ColorInt int color) { |
||||||
|
mEditor.putInt(KEY_PRIMARY_COLOR_DARK, color); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ThemeStore primaryColorDarkRes(@ColorRes int colorRes) { |
||||||
|
return primaryColorDark(ContextCompat.getColor(mContext, colorRes)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ThemeStore primaryColorDarkAttr(@AttrRes int colorAttr) { |
||||||
|
return primaryColorDark(ATHUtil.resolveColor(mContext, colorAttr)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ThemeStore accentColor(@ColorInt int color) { |
||||||
|
mEditor.putInt(KEY_ACCENT_COLOR, color); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ThemeStore accentColorRes(@ColorRes int colorRes) { |
||||||
|
return accentColor(ContextCompat.getColor(mContext, colorRes)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ThemeStore accentColorAttr(@AttrRes int colorAttr) { |
||||||
|
return accentColor(ATHUtil.resolveColor(mContext, colorAttr)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ThemeStore statusBarColor(@ColorInt int color) { |
||||||
|
mEditor.putInt(KEY_STATUS_BAR_COLOR, color); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ThemeStore statusBarColorRes(@ColorRes int colorRes) { |
||||||
|
return statusBarColor(ContextCompat.getColor(mContext, colorRes)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ThemeStore statusBarColorAttr(@AttrRes int colorAttr) { |
||||||
|
return statusBarColor(ATHUtil.resolveColor(mContext, colorAttr)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ThemeStore navigationBarColor(@ColorInt int color) { |
||||||
|
mEditor.putInt(KEY_NAVIGATION_BAR_COLOR, color); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ThemeStore navigationBarColorRes(@ColorRes int colorRes) { |
||||||
|
return navigationBarColor(ContextCompat.getColor(mContext, colorRes)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ThemeStore navigationBarColorAttr(@AttrRes int colorAttr) { |
||||||
|
return navigationBarColor(ATHUtil.resolveColor(mContext, colorAttr)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ThemeStore textColorPrimary(@ColorInt int color) { |
||||||
|
mEditor.putInt(KEY_TEXT_COLOR_PRIMARY, color); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ThemeStore textColorPrimaryRes(@ColorRes int colorRes) { |
||||||
|
return textColorPrimary(ContextCompat.getColor(mContext, colorRes)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ThemeStore textColorPrimaryAttr(@AttrRes int colorAttr) { |
||||||
|
return textColorPrimary(ATHUtil.resolveColor(mContext, colorAttr)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ThemeStore textColorPrimaryInverse(@ColorInt int color) { |
||||||
|
mEditor.putInt(KEY_TEXT_COLOR_PRIMARY_INVERSE, color); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ThemeStore textColorPrimaryInverseRes(@ColorRes int colorRes) { |
||||||
|
return textColorPrimaryInverse(ContextCompat.getColor(mContext, colorRes)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ThemeStore textColorPrimaryInverseAttr(@AttrRes int colorAttr) { |
||||||
|
return textColorPrimaryInverse(ATHUtil.resolveColor(mContext, colorAttr)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ThemeStore textColorSecondary(@ColorInt int color) { |
||||||
|
mEditor.putInt(KEY_TEXT_COLOR_SECONDARY, color); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ThemeStore textColorSecondaryRes(@ColorRes int colorRes) { |
||||||
|
return textColorSecondary(ContextCompat.getColor(mContext, colorRes)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ThemeStore textColorSecondaryAttr(@AttrRes int colorAttr) { |
||||||
|
return textColorSecondary(ATHUtil.resolveColor(mContext, colorAttr)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ThemeStore textColorSecondaryInverse(@ColorInt int color) { |
||||||
|
mEditor.putInt(KEY_TEXT_COLOR_SECONDARY_INVERSE, color); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ThemeStore textColorSecondaryInverseRes(@ColorRes int colorRes) { |
||||||
|
return textColorSecondaryInverse(ContextCompat.getColor(mContext, colorRes)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ThemeStore textColorSecondaryInverseAttr(@AttrRes int colorAttr) { |
||||||
|
return textColorSecondaryInverse(ATHUtil.resolveColor(mContext, colorAttr)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ThemeStore backgroundColor(int color) { |
||||||
|
mEditor.putInt(KEY_BACKGROUND_COLOR, color); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ThemeStore coloredStatusBar(boolean colored) { |
||||||
|
mEditor.putBoolean(KEY_APPLY_PRIMARYDARK_STATUSBAR, colored); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ThemeStore coloredNavigationBar(boolean applyToNavBar) { |
||||||
|
mEditor.putBoolean(KEY_APPLY_PRIMARY_NAVBAR, applyToNavBar); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public ThemeStore autoGeneratePrimaryDark(boolean autoGenerate) { |
||||||
|
mEditor.putBoolean(KEY_AUTO_GENERATE_PRIMARYDARK, autoGenerate); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
// Commit method
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked") |
||||||
|
@Override |
||||||
|
public void apply() { |
||||||
|
mEditor.putLong(VALUES_CHANGED, System.currentTimeMillis()) |
||||||
|
.putBoolean(IS_CONFIGURED_KEY, true) |
||||||
|
.apply(); |
||||||
|
} |
||||||
|
|
||||||
|
// Static getters
|
||||||
|
|
||||||
|
@CheckResult |
||||||
|
@NonNull |
||||||
|
protected static SharedPreferences prefs(@NonNull Context context) { |
||||||
|
return context.getSharedPreferences(CONFIG_PREFS_KEY_DEFAULT, Context.MODE_PRIVATE); |
||||||
|
} |
||||||
|
|
||||||
|
public static void markChanged(@NonNull Context context) { |
||||||
|
new ThemeStore(context).apply(); |
||||||
|
} |
||||||
|
|
||||||
|
@CheckResult |
||||||
|
@ColorInt |
||||||
|
public static int primaryColor(@NonNull Context context) { |
||||||
|
return prefs(context).getInt(KEY_PRIMARY_COLOR, ATHUtil.resolveColor(context, R.attr.colorPrimary, Color.parseColor("#455A64"))); |
||||||
|
} |
||||||
|
|
||||||
|
@CheckResult |
||||||
|
@ColorInt |
||||||
|
public static int primaryColorDark(@NonNull Context context) { |
||||||
|
return prefs(context).getInt(KEY_PRIMARY_COLOR_DARK, ATHUtil.resolveColor(context, R.attr.colorPrimaryDark, Color.parseColor("#37474F"))); |
||||||
|
} |
||||||
|
|
||||||
|
@CheckResult |
||||||
|
@ColorInt |
||||||
|
public static int accentColor(@NonNull Context context) { |
||||||
|
return prefs(context).getInt(KEY_ACCENT_COLOR, ATHUtil.resolveColor(context, R.attr.colorAccent, Color.parseColor("#263238"))); |
||||||
|
} |
||||||
|
|
||||||
|
@CheckResult |
||||||
|
@ColorInt |
||||||
|
public static int statusBarColor(@NonNull Context context) { |
||||||
|
if (!coloredStatusBar(context)) { |
||||||
|
return Color.BLACK; |
||||||
|
} |
||||||
|
return prefs(context).getInt(KEY_STATUS_BAR_COLOR, primaryColorDark(context)); |
||||||
|
} |
||||||
|
|
||||||
|
@CheckResult |
||||||
|
@ColorInt |
||||||
|
public static int navigationBarColor(@NonNull Context context) { |
||||||
|
if (!coloredNavigationBar(context)) { |
||||||
|
return Color.BLACK; |
||||||
|
} |
||||||
|
return prefs(context).getInt(KEY_NAVIGATION_BAR_COLOR, primaryColor(context)); |
||||||
|
} |
||||||
|
|
||||||
|
@CheckResult |
||||||
|
@ColorInt |
||||||
|
public static int textColorPrimary(@NonNull Context context) { |
||||||
|
return prefs(context).getInt(KEY_TEXT_COLOR_PRIMARY, ATHUtil.resolveColor(context, android.R.attr.textColorPrimary)); |
||||||
|
} |
||||||
|
|
||||||
|
@CheckResult |
||||||
|
@ColorInt |
||||||
|
public static int textColorPrimaryInverse(@NonNull Context context) { |
||||||
|
return prefs(context).getInt(KEY_TEXT_COLOR_PRIMARY_INVERSE, ATHUtil.resolveColor(context, android.R.attr.textColorPrimaryInverse)); |
||||||
|
} |
||||||
|
|
||||||
|
@CheckResult |
||||||
|
@ColorInt |
||||||
|
public static int textColorSecondary(@NonNull Context context) { |
||||||
|
return prefs(context).getInt(KEY_TEXT_COLOR_SECONDARY, ATHUtil.resolveColor(context, android.R.attr.textColorSecondary)); |
||||||
|
} |
||||||
|
|
||||||
|
@CheckResult |
||||||
|
@ColorInt |
||||||
|
public static int textColorSecondaryInverse(@NonNull Context context) { |
||||||
|
return prefs(context).getInt(KEY_TEXT_COLOR_SECONDARY_INVERSE, ATHUtil.resolveColor(context, android.R.attr.textColorSecondaryInverse)); |
||||||
|
} |
||||||
|
|
||||||
|
@CheckResult |
||||||
|
@ColorInt |
||||||
|
public static int backgroundColor(@NonNull Context context) { |
||||||
|
return prefs(context).getInt(KEY_BACKGROUND_COLOR, ATHUtil.resolveColor(context, android.R.attr.colorBackground)); |
||||||
|
} |
||||||
|
|
||||||
|
@CheckResult |
||||||
|
public static boolean coloredStatusBar(@NonNull Context context) { |
||||||
|
return prefs(context).getBoolean(KEY_APPLY_PRIMARYDARK_STATUSBAR, true); |
||||||
|
} |
||||||
|
|
||||||
|
@CheckResult |
||||||
|
public static boolean coloredNavigationBar(@NonNull Context context) { |
||||||
|
return prefs(context).getBoolean(KEY_APPLY_PRIMARY_NAVBAR, false); |
||||||
|
} |
||||||
|
|
||||||
|
@CheckResult |
||||||
|
public static boolean autoGeneratePrimaryDark(@NonNull Context context) { |
||||||
|
return prefs(context).getBoolean(KEY_AUTO_GENERATE_PRIMARYDARK, true); |
||||||
|
} |
||||||
|
|
||||||
|
@CheckResult |
||||||
|
public static boolean isConfigured(Context context) { |
||||||
|
return prefs(context).getBoolean(IS_CONFIGURED_KEY, false); |
||||||
|
} |
||||||
|
|
||||||
|
@SuppressLint("CommitPrefEdits") |
||||||
|
public static boolean isConfigured(Context context, @IntRange(from = 0, to = Integer.MAX_VALUE) int version) { |
||||||
|
final SharedPreferences prefs = prefs(context); |
||||||
|
final int lastVersion = prefs.getInt(IS_CONFIGURED_VERSION_KEY, -1); |
||||||
|
if (version > lastVersion) { |
||||||
|
prefs.edit().putInt(IS_CONFIGURED_VERSION_KEY, version).apply(); |
||||||
|
return false; |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,92 @@ |
|||||||
|
package io.legado.app.lib.theme; |
||||||
|
|
||||||
|
|
||||||
|
import androidx.annotation.AttrRes; |
||||||
|
import androidx.annotation.ColorInt; |
||||||
|
import androidx.annotation.ColorRes; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Aidan Follestad (afollestad), Karim Abou Zeid (kabouzeid) |
||||||
|
*/ |
||||||
|
interface ThemeStoreInterface { |
||||||
|
|
||||||
|
// Primary colors
|
||||||
|
|
||||||
|
ThemeStore primaryColor(@ColorInt int color); |
||||||
|
|
||||||
|
ThemeStore primaryColorRes(@ColorRes int colorRes); |
||||||
|
|
||||||
|
ThemeStore primaryColorAttr(@AttrRes int colorAttr); |
||||||
|
|
||||||
|
ThemeStore autoGeneratePrimaryDark(boolean autoGenerate); |
||||||
|
|
||||||
|
ThemeStore primaryColorDark(@ColorInt int color); |
||||||
|
|
||||||
|
ThemeStore primaryColorDarkRes(@ColorRes int colorRes); |
||||||
|
|
||||||
|
ThemeStore primaryColorDarkAttr(@AttrRes int colorAttr); |
||||||
|
|
||||||
|
// Accent colors
|
||||||
|
|
||||||
|
ThemeStore accentColor(@ColorInt int color); |
||||||
|
|
||||||
|
ThemeStore accentColorRes(@ColorRes int colorRes); |
||||||
|
|
||||||
|
ThemeStore accentColorAttr(@AttrRes int colorAttr); |
||||||
|
|
||||||
|
// Status bar color
|
||||||
|
|
||||||
|
ThemeStore statusBarColor(@ColorInt int color); |
||||||
|
|
||||||
|
ThemeStore statusBarColorRes(@ColorRes int colorRes); |
||||||
|
|
||||||
|
ThemeStore statusBarColorAttr(@AttrRes int colorAttr); |
||||||
|
|
||||||
|
// Navigation bar color
|
||||||
|
|
||||||
|
ThemeStore navigationBarColor(@ColorInt int color); |
||||||
|
|
||||||
|
ThemeStore navigationBarColorRes(@ColorRes int colorRes); |
||||||
|
|
||||||
|
ThemeStore navigationBarColorAttr(@AttrRes int colorAttr); |
||||||
|
|
||||||
|
// Primary text color
|
||||||
|
|
||||||
|
ThemeStore textColorPrimary(@ColorInt int color); |
||||||
|
|
||||||
|
ThemeStore textColorPrimaryRes(@ColorRes int colorRes); |
||||||
|
|
||||||
|
ThemeStore textColorPrimaryAttr(@AttrRes int colorAttr); |
||||||
|
|
||||||
|
ThemeStore textColorPrimaryInverse(@ColorInt int color); |
||||||
|
|
||||||
|
ThemeStore textColorPrimaryInverseRes(@ColorRes int colorRes); |
||||||
|
|
||||||
|
ThemeStore textColorPrimaryInverseAttr(@AttrRes int colorAttr); |
||||||
|
|
||||||
|
// Secondary text color
|
||||||
|
|
||||||
|
ThemeStore textColorSecondary(@ColorInt int color); |
||||||
|
|
||||||
|
ThemeStore textColorSecondaryRes(@ColorRes int colorRes); |
||||||
|
|
||||||
|
ThemeStore textColorSecondaryAttr(@AttrRes int colorAttr); |
||||||
|
|
||||||
|
ThemeStore textColorSecondaryInverse(@ColorInt int color); |
||||||
|
|
||||||
|
ThemeStore textColorSecondaryInverseRes(@ColorRes int colorRes); |
||||||
|
|
||||||
|
ThemeStore textColorSecondaryInverseAttr(@AttrRes int colorAttr); |
||||||
|
|
||||||
|
ThemeStore backgroundColor(@ColorInt int color); |
||||||
|
|
||||||
|
// Toggle configurations
|
||||||
|
|
||||||
|
ThemeStore coloredStatusBar(boolean colored); |
||||||
|
|
||||||
|
ThemeStore coloredNavigationBar(boolean applyToNavBar); |
||||||
|
|
||||||
|
// Commit/apply
|
||||||
|
|
||||||
|
void apply(); |
||||||
|
} |
@ -0,0 +1,29 @@ |
|||||||
|
package io.legado.app.lib.theme; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Aidan Follestad (afollestad), Karim Abou Zeid (kabouzeid) |
||||||
|
*/ |
||||||
|
interface ThemeStorePrefKeys { |
||||||
|
|
||||||
|
String CONFIG_PREFS_KEY_DEFAULT = "[[kabouzeid_app-theme-helper]]"; |
||||||
|
String IS_CONFIGURED_KEY = "is_configured"; |
||||||
|
String IS_CONFIGURED_VERSION_KEY = "is_configured_version"; |
||||||
|
String VALUES_CHANGED = "values_changed"; |
||||||
|
|
||||||
|
String KEY_PRIMARY_COLOR = "primary_color"; |
||||||
|
String KEY_PRIMARY_COLOR_DARK = "primary_color_dark"; |
||||||
|
String KEY_ACCENT_COLOR = "accent_color"; |
||||||
|
String KEY_STATUS_BAR_COLOR = "status_bar_color"; |
||||||
|
String KEY_NAVIGATION_BAR_COLOR = "navigation_bar_color"; |
||||||
|
|
||||||
|
String KEY_TEXT_COLOR_PRIMARY = "text_color_primary"; |
||||||
|
String KEY_TEXT_COLOR_PRIMARY_INVERSE = "text_color_primary_inverse"; |
||||||
|
String KEY_TEXT_COLOR_SECONDARY = "text_color_secondary"; |
||||||
|
String KEY_TEXT_COLOR_SECONDARY_INVERSE = "text_color_secondary_inverse"; |
||||||
|
|
||||||
|
String KEY_BACKGROUND_COLOR = "backgroundColor"; |
||||||
|
|
||||||
|
String KEY_APPLY_PRIMARYDARK_STATUSBAR = "apply_primarydark_statusbar"; |
||||||
|
String KEY_APPLY_PRIMARY_NAVBAR = "apply_primary_navbar"; |
||||||
|
String KEY_AUTO_GENERATE_PRIMARYDARK = "auto_generate_primarydark"; |
||||||
|
} |
@ -0,0 +1,384 @@ |
|||||||
|
package io.legado.app.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.os.Build; |
||||||
|
import android.view.View; |
||||||
|
import android.widget.*; |
||||||
|
import androidx.annotation.CheckResult; |
||||||
|
import androidx.annotation.ColorInt; |
||||||
|
import androidx.annotation.NonNull; |
||||||
|
import androidx.annotation.Nullable; |
||||||
|
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 com.google.android.material.floatingactionbutton.FloatingActionButton; |
||||||
|
import io.legado.app.R; |
||||||
|
|
||||||
|
import java.lang.reflect.Field; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author afollestad, plusCubed |
||||||
|
*/ |
||||||
|
public final class TintHelper { |
||||||
|
|
||||||
|
@SuppressLint("PrivateResource") |
||||||
|
@ColorInt |
||||||
|
private static int getDefaultRippleColor(@NonNull Context context, boolean useDarkRipple) { |
||||||
|
// Light ripple is actually translucent black, and vice versa
|
||||||
|
return ContextCompat.getColor(context, useDarkRipple ? |
||||||
|
R.color.ripple_material_light : R.color.ripple_material_dark); |
||||||
|
} |
||||||
|
|
||||||
|
@NonNull |
||||||
|
private static ColorStateList getDisabledColorStateList(@ColorInt int normal, @ColorInt int disabled) { |
||||||
|
return new ColorStateList(new int[][]{ |
||||||
|
new int[]{-android.R.attr.state_enabled}, |
||||||
|
new int[]{android.R.attr.state_enabled} |
||||||
|
}, new int[]{ |
||||||
|
disabled, |
||||||
|
normal |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@SuppressWarnings("deprecation") |
||||||
|
public static void setTintSelector(@NonNull View view, @ColorInt final int color, final boolean darker, final boolean useDarkTheme) { |
||||||
|
final boolean isColorLight = ColorUtil.isColorLight(color); |
||||||
|
final int disabled = ContextCompat.getColor(view.getContext(), useDarkTheme ? R.color.ate_button_disabled_dark : R.color.ate_button_disabled_light); |
||||||
|
final int pressed = ColorUtil.shiftColor(color, darker ? 0.9f : 1.1f); |
||||||
|
final int activated = ColorUtil.shiftColor(color, darker ? 1.1f : 0.9f); |
||||||
|
final int rippleColor = getDefaultRippleColor(view.getContext(), isColorLight); |
||||||
|
final int textColor = ContextCompat.getColor(view.getContext(), isColorLight ? R.color.ate_primary_text_light : R.color.ate_primary_text_dark); |
||||||
|
|
||||||
|
final ColorStateList sl; |
||||||
|
if (view instanceof Button) { |
||||||
|
sl = getDisabledColorStateList(color, disabled); |
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && |
||||||
|
view.getBackground() instanceof RippleDrawable) { |
||||||
|
RippleDrawable rd = (RippleDrawable) view.getBackground(); |
||||||
|
rd.setColor(ColorStateList.valueOf(rippleColor)); |
||||||
|
} |
||||||
|
|
||||||
|
// Disabled text color state for buttons, may get overridden later by ATE tags
|
||||||
|
final Button button = (Button) view; |
||||||
|
button.setTextColor(getDisabledColorStateList(textColor, ContextCompat.getColor(view.getContext(), useDarkTheme ? R.color.ate_button_text_disabled_dark : R.color.ate_button_text_disabled_light))); |
||||||
|
} else if (view instanceof FloatingActionButton) { |
||||||
|
// FloatingActionButton doesn't support disabled state?
|
||||||
|
sl = new ColorStateList(new int[][]{ |
||||||
|
new int[]{-android.R.attr.state_pressed}, |
||||||
|
new int[]{android.R.attr.state_pressed} |
||||||
|
}, new int[]{ |
||||||
|
color, |
||||||
|
pressed |
||||||
|
}); |
||||||
|
|
||||||
|
final FloatingActionButton fab = (FloatingActionButton) view; |
||||||
|
fab.setRippleColor(rippleColor); |
||||||
|
fab.setBackgroundTintList(sl); |
||||||
|
if (fab.getDrawable() != null) |
||||||
|
fab.setImageDrawable(createTintedDrawable(fab.getDrawable(), textColor)); |
||||||
|
return; |
||||||
|
} else { |
||||||
|
sl = new ColorStateList( |
||||||
|
new int[][]{ |
||||||
|
new int[]{-android.R.attr.state_enabled}, |
||||||
|
new int[]{android.R.attr.state_enabled}, |
||||||
|
new int[]{android.R.attr.state_enabled, android.R.attr.state_pressed}, |
||||||
|
new int[]{android.R.attr.state_enabled, android.R.attr.state_activated}, |
||||||
|
new int[]{android.R.attr.state_enabled, android.R.attr.state_checked} |
||||||
|
}, |
||||||
|
new int[]{ |
||||||
|
disabled, |
||||||
|
color, |
||||||
|
pressed, |
||||||
|
activated, |
||||||
|
activated |
||||||
|
} |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
Drawable drawable = view.getBackground(); |
||||||
|
if (drawable != null) { |
||||||
|
drawable = createTintedDrawable(drawable, sl); |
||||||
|
ViewUtil.setBackgroundCompat(view, drawable); |
||||||
|
} |
||||||
|
|
||||||
|
if (view instanceof TextView && !(view instanceof Button)) { |
||||||
|
final TextView tv = (TextView) view; |
||||||
|
tv.setTextColor(getDisabledColorStateList(textColor, ContextCompat.getColor(view.getContext(), isColorLight ? R.color.ate_text_disabled_light : R.color.ate_text_disabled_dark))); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void setTintAuto(final @NonNull View view, final @ColorInt int color, |
||||||
|
boolean background) { |
||||||
|
setTintAuto(view, color, background, ATHUtil.isWindowBackgroundDark(view.getContext())); |
||||||
|
} |
||||||
|
|
||||||
|
@SuppressWarnings("deprecation") |
||||||
|
public static void setTintAuto(final @NonNull View view, final @ColorInt int color, |
||||||
|
boolean background, final boolean isDark) { |
||||||
|
if (!background) { |
||||||
|
if (view instanceof RadioButton) |
||||||
|
setTint((RadioButton) view, color, isDark); |
||||||
|
else if (view instanceof SeekBar) |
||||||
|
setTint((SeekBar) view, color, isDark); |
||||||
|
else if (view instanceof ProgressBar) |
||||||
|
setTint((ProgressBar) view, color); |
||||||
|
else if (view instanceof AppCompatEditText) |
||||||
|
setTint((AppCompatEditText) view, color, isDark); |
||||||
|
else if (view instanceof CheckBox) |
||||||
|
setTint((CheckBox) view, color, isDark); |
||||||
|
else if (view instanceof ImageView) |
||||||
|
setTint((ImageView) view, color); |
||||||
|
else if (view instanceof Switch) |
||||||
|
setTint((Switch) view, color, isDark); |
||||||
|
else if (view instanceof SwitchCompat) |
||||||
|
setTint((SwitchCompat) view, color, isDark); |
||||||
|
else if (view instanceof SearchView) { |
||||||
|
int iconIdS[] = new int[]{androidx.appcompat.R.id.search_button, androidx.appcompat.R.id.search_close_btn,}; |
||||||
|
for (int iconId : iconIdS) { |
||||||
|
ImageView icon = view.findViewById(iconId); |
||||||
|
if (icon != null) { |
||||||
|
setTint(icon, color); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} else { |
||||||
|
background = true; |
||||||
|
} |
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && |
||||||
|
!background && view.getBackground() instanceof RippleDrawable) { |
||||||
|
// Ripples for the above views (e.g. when you tap and hold a switch or checkbox)
|
||||||
|
RippleDrawable rd = (RippleDrawable) view.getBackground(); |
||||||
|
@SuppressLint("PrivateResource") final int unchecked = ContextCompat.getColor(view.getContext(), |
||||||
|
isDark ? R.color.ripple_material_dark : R.color.ripple_material_light); |
||||||
|
final int checked = ColorUtil.adjustAlpha(color, 0.4f); |
||||||
|
final ColorStateList sl = new ColorStateList( |
||||||
|
new int[][]{ |
||||||
|
new int[]{-android.R.attr.state_activated, -android.R.attr.state_checked}, |
||||||
|
new int[]{android.R.attr.state_activated}, |
||||||
|
new int[]{android.R.attr.state_checked} |
||||||
|
}, |
||||||
|
new int[]{ |
||||||
|
unchecked, |
||||||
|
checked, |
||||||
|
checked |
||||||
|
} |
||||||
|
); |
||||||
|
rd.setColor(sl); |
||||||
|
} |
||||||
|
} |
||||||
|
if (background) { |
||||||
|
// Need to tint the background of a view
|
||||||
|
if (view instanceof FloatingActionButton || view instanceof Button) { |
||||||
|
setTintSelector(view, color, false, isDark); |
||||||
|
} else if (view.getBackground() != null) { |
||||||
|
Drawable drawable = view.getBackground(); |
||||||
|
if (drawable != null) { |
||||||
|
drawable = createTintedDrawable(drawable, color); |
||||||
|
ViewUtil.setBackgroundCompat(view, drawable); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void setTint(@NonNull RadioButton radioButton, @ColorInt int color, boolean useDarker) { |
||||||
|
ColorStateList sl = new ColorStateList(new int[][]{ |
||||||
|
new int[]{-android.R.attr.state_enabled}, |
||||||
|
new int[]{android.R.attr.state_enabled, -android.R.attr.state_checked}, |
||||||
|
new int[]{android.R.attr.state_enabled, android.R.attr.state_checked} |
||||||
|
}, new int[]{ |
||||||
|
// Rdio button includes own alpha for disabled state
|
||||||
|
ColorUtil.stripAlpha(ContextCompat.getColor(radioButton.getContext(), useDarker ? R.color.ate_control_disabled_dark : R.color.ate_control_disabled_light)), |
||||||
|
ContextCompat.getColor(radioButton.getContext(), useDarker ? R.color.ate_control_normal_dark : R.color.ate_control_normal_light), |
||||||
|
color |
||||||
|
}); |
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { |
||||||
|
radioButton.setButtonTintList(sl); |
||||||
|
} else { |
||||||
|
Drawable d = createTintedDrawable(ContextCompat.getDrawable(radioButton.getContext(), R.drawable.abc_btn_radio_material), sl); |
||||||
|
radioButton.setButtonDrawable(d); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void setTint(@NonNull SeekBar seekBar, @ColorInt int color, boolean useDarker) { |
||||||
|
final ColorStateList s1 = getDisabledColorStateList(color, |
||||||
|
ContextCompat.getColor(seekBar.getContext(), useDarker ? R.color.ate_control_disabled_dark : R.color.ate_control_disabled_light)); |
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { |
||||||
|
seekBar.setThumbTintList(s1); |
||||||
|
seekBar.setProgressTintList(s1); |
||||||
|
} else { |
||||||
|
Drawable progressDrawable = createTintedDrawable(seekBar.getProgressDrawable(), s1); |
||||||
|
seekBar.setProgressDrawable(progressDrawable); |
||||||
|
Drawable thumbDrawable = createTintedDrawable(seekBar.getThumb(), s1); |
||||||
|
seekBar.setThumb(thumbDrawable); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void setTint(@NonNull ProgressBar progressBar, @ColorInt int color) { |
||||||
|
setTint(progressBar, color, false); |
||||||
|
} |
||||||
|
|
||||||
|
public static void setTint(@NonNull ProgressBar progressBar, @ColorInt int color, boolean skipIndeterminate) { |
||||||
|
ColorStateList sl = ColorStateList.valueOf(color); |
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { |
||||||
|
progressBar.setProgressTintList(sl); |
||||||
|
progressBar.setSecondaryProgressTintList(sl); |
||||||
|
if (!skipIndeterminate) |
||||||
|
progressBar.setIndeterminateTintList(sl); |
||||||
|
} else { |
||||||
|
PorterDuff.Mode mode = PorterDuff.Mode.SRC_IN; |
||||||
|
if (!skipIndeterminate && progressBar.getIndeterminateDrawable() != null) |
||||||
|
progressBar.getIndeterminateDrawable().setColorFilter(color, mode); |
||||||
|
if (progressBar.getProgressDrawable() != null) |
||||||
|
progressBar.getProgressDrawable().setColorFilter(color, mode); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@SuppressLint("RestrictedApi") |
||||||
|
public static void setTint(@NonNull AppCompatEditText editText, @ColorInt int color, boolean useDarker) { |
||||||
|
final ColorStateList editTextColorStateList = new ColorStateList(new int[][]{ |
||||||
|
new int[]{-android.R.attr.state_enabled}, |
||||||
|
new int[]{android.R.attr.state_enabled, -android.R.attr.state_pressed, -android.R.attr.state_focused}, |
||||||
|
new int[]{} |
||||||
|
}, new int[]{ |
||||||
|
ContextCompat.getColor(editText.getContext(), useDarker ? R.color.ate_text_disabled_dark : R.color.ate_text_disabled_light), |
||||||
|
ContextCompat.getColor(editText.getContext(), useDarker ? R.color.ate_control_normal_dark : R.color.ate_control_normal_light), |
||||||
|
color |
||||||
|
}); |
||||||
|
editText.setSupportBackgroundTintList(editTextColorStateList); |
||||||
|
setCursorTint(editText, color); |
||||||
|
} |
||||||
|
|
||||||
|
public static void setTint(@NonNull CheckBox box, @ColorInt int color, boolean useDarker) { |
||||||
|
ColorStateList sl = new ColorStateList(new int[][]{ |
||||||
|
new int[]{-android.R.attr.state_enabled}, |
||||||
|
new int[]{android.R.attr.state_enabled, -android.R.attr.state_checked}, |
||||||
|
new int[]{android.R.attr.state_enabled, android.R.attr.state_checked} |
||||||
|
}, new int[]{ |
||||||
|
ContextCompat.getColor(box.getContext(), useDarker ? R.color.ate_control_disabled_dark : R.color.ate_control_disabled_light), |
||||||
|
ContextCompat.getColor(box.getContext(), useDarker ? R.color.ate_control_normal_dark : R.color.ate_control_normal_light), |
||||||
|
color |
||||||
|
}); |
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { |
||||||
|
box.setButtonTintList(sl); |
||||||
|
} else { |
||||||
|
Drawable drawable = createTintedDrawable(ContextCompat.getDrawable(box.getContext(), R.drawable.abc_btn_check_material), sl); |
||||||
|
box.setButtonDrawable(drawable); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void setTint(@NonNull ImageView image, @ColorInt int color) { |
||||||
|
image.setColorFilter(color, PorterDuff.Mode.SRC_ATOP); |
||||||
|
} |
||||||
|
|
||||||
|
private static Drawable modifySwitchDrawable(@NonNull Context context, @NonNull Drawable from, @ColorInt int tint, boolean thumb, boolean compatSwitch, boolean useDarker) { |
||||||
|
if (useDarker) { |
||||||
|
tint = ColorUtil.shiftColor(tint, 1.1f); |
||||||
|
} |
||||||
|
tint = ColorUtil.adjustAlpha(tint, (compatSwitch && !thumb) ? 0.5f : 1.0f); |
||||||
|
int disabled; |
||||||
|
int normal; |
||||||
|
if (thumb) { |
||||||
|
disabled = ContextCompat.getColor(context, useDarker ? R.color.ate_switch_thumb_disabled_dark : R.color.ate_switch_thumb_disabled_light); |
||||||
|
normal = ContextCompat.getColor(context, useDarker ? R.color.ate_switch_thumb_normal_dark : R.color.ate_switch_thumb_normal_light); |
||||||
|
} else { |
||||||
|
disabled = ContextCompat.getColor(context, useDarker ? R.color.ate_switch_track_disabled_dark : R.color.ate_switch_track_disabled_light); |
||||||
|
normal = ContextCompat.getColor(context, useDarker ? R.color.ate_switch_track_normal_dark : R.color.ate_switch_track_normal_light); |
||||||
|
} |
||||||
|
|
||||||
|
// Stock switch includes its own alpha
|
||||||
|
if (!compatSwitch) { |
||||||
|
normal = ColorUtil.stripAlpha(normal); |
||||||
|
} |
||||||
|
|
||||||
|
final ColorStateList sl = new ColorStateList( |
||||||
|
new int[][]{ |
||||||
|
new int[]{-android.R.attr.state_enabled}, |
||||||
|
new int[]{android.R.attr.state_enabled, -android.R.attr.state_activated, -android.R.attr.state_checked}, |
||||||
|
new int[]{android.R.attr.state_enabled, android.R.attr.state_activated}, |
||||||
|
new int[]{android.R.attr.state_enabled, android.R.attr.state_checked} |
||||||
|
}, |
||||||
|
new int[]{ |
||||||
|
disabled, |
||||||
|
normal, |
||||||
|
tint, |
||||||
|
tint |
||||||
|
} |
||||||
|
); |
||||||
|
return createTintedDrawable(from, sl); |
||||||
|
} |
||||||
|
|
||||||
|
public static void setTint(@NonNull Switch switchView, @ColorInt int color, boolean useDarker) { |
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) return; |
||||||
|
if (switchView.getTrackDrawable() != null) { |
||||||
|
switchView.setTrackDrawable(modifySwitchDrawable(switchView.getContext(), |
||||||
|
switchView.getTrackDrawable(), color, false, false, useDarker)); |
||||||
|
} |
||||||
|
if (switchView.getThumbDrawable() != null) { |
||||||
|
switchView.setThumbDrawable(modifySwitchDrawable(switchView.getContext(), |
||||||
|
switchView.getThumbDrawable(), color, true, false, useDarker)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void setTint(@NonNull SwitchCompat switchView, @ColorInt int color, boolean useDarker) { |
||||||
|
if (switchView.getTrackDrawable() != null) { |
||||||
|
switchView.setTrackDrawable(modifySwitchDrawable(switchView.getContext(), |
||||||
|
switchView.getTrackDrawable(), color, false, true, useDarker)); |
||||||
|
} |
||||||
|
if (switchView.getThumbDrawable() != null) { |
||||||
|
switchView.setThumbDrawable(modifySwitchDrawable(switchView.getContext(), |
||||||
|
switchView.getThumbDrawable(), color, true, true, 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 |
||||||
|
@Nullable |
||||||
|
public static Drawable createTintedDrawable(@Nullable Drawable drawable, @ColorInt int color) { |
||||||
|
if (drawable == null) return null; |
||||||
|
drawable = DrawableCompat.wrap(drawable.mutate()); |
||||||
|
DrawableCompat.setTintMode(drawable, PorterDuff.Mode.SRC_IN); |
||||||
|
DrawableCompat.setTint(drawable, color); |
||||||
|
return drawable; |
||||||
|
} |
||||||
|
|
||||||
|
// 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 |
||||||
|
@Nullable |
||||||
|
public static Drawable createTintedDrawable(@Nullable Drawable drawable, @NonNull ColorStateList sl) { |
||||||
|
if (drawable == null) return null; |
||||||
|
drawable = DrawableCompat.wrap(drawable.mutate()); |
||||||
|
DrawableCompat.setTintList(drawable, sl); |
||||||
|
return drawable; |
||||||
|
} |
||||||
|
|
||||||
|
public static void setCursorTint(@NonNull EditText editText, @ColorInt int color) { |
||||||
|
try { |
||||||
|
Field fCursorDrawableRes = TextView.class.getDeclaredField("mCursorDrawableRes"); |
||||||
|
fCursorDrawableRes.setAccessible(true); |
||||||
|
int mCursorDrawableRes = fCursorDrawableRes.getInt(editText); |
||||||
|
Field fEditor = TextView.class.getDeclaredField("mEditor"); |
||||||
|
fEditor.setAccessible(true); |
||||||
|
Object editor = fEditor.get(editText); |
||||||
|
Class<?> clazz = editor.getClass(); |
||||||
|
Field fCursorDrawable = clazz.getDeclaredField("mCursorDrawable"); |
||||||
|
fCursorDrawable.setAccessible(true); |
||||||
|
Drawable[] drawables = new Drawable[2]; |
||||||
|
drawables[0] = ContextCompat.getDrawable(editText.getContext(), mCursorDrawableRes); |
||||||
|
drawables[0] = createTintedDrawable(drawables[0], color); |
||||||
|
drawables[1] = ContextCompat.getDrawable(editText.getContext(), mCursorDrawableRes); |
||||||
|
drawables[1] = createTintedDrawable(drawables[1], color); |
||||||
|
fCursorDrawable.set(editor, drawables); |
||||||
|
} catch (Exception ignored) { |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,48 @@ |
|||||||
|
package io.legado.app.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 androidx.annotation.NonNull; |
||||||
|
import androidx.annotation.Nullable; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Karim Abou Zeid (kabouzeid) |
||||||
|
*/ |
||||||
|
public final class ViewUtil { |
||||||
|
|
||||||
|
@SuppressWarnings("deprecation") |
||||||
|
public static void removeOnGlobalLayoutListener(View v, ViewTreeObserver.OnGlobalLayoutListener listener) { |
||||||
|
v.getViewTreeObserver().removeOnGlobalLayoutListener(listener); |
||||||
|
} |
||||||
|
|
||||||
|
@SuppressWarnings("deprecation") |
||||||
|
public static void setBackgroundCompat(@NonNull View view, @Nullable Drawable drawable) { |
||||||
|
view.setBackground(drawable); |
||||||
|
} |
||||||
|
|
||||||
|
public static TransitionDrawable setBackgroundTransition(@NonNull View view, @NonNull Drawable newDrawable) { |
||||||
|
TransitionDrawable transition = DrawableUtil.createTransitionDrawable(view.getBackground(), newDrawable); |
||||||
|
setBackgroundCompat(view, transition); |
||||||
|
return transition; |
||||||
|
} |
||||||
|
|
||||||
|
public static TransitionDrawable setBackgroundColorTransition(@NonNull View view, @ColorInt int newColor) { |
||||||
|
final Drawable oldColor = view.getBackground(); |
||||||
|
|
||||||
|
Drawable start = oldColor != null ? oldColor : new ColorDrawable(view.getSolidColor()); |
||||||
|
Drawable end = new ColorDrawable(newColor); |
||||||
|
|
||||||
|
TransitionDrawable transition = DrawableUtil.createTransitionDrawable(start, end); |
||||||
|
|
||||||
|
setBackgroundCompat(view, transition); |
||||||
|
|
||||||
|
return transition; |
||||||
|
} |
||||||
|
|
||||||
|
private ViewUtil() { |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,34 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<resources> |
||||||
|
<color name="background">@color/md_grey_800</color> |
||||||
|
<color name="background_card">#353535</color> |
||||||
|
<color name="background_menu">#282828</color> |
||||||
|
|
||||||
|
<color name="night_mask">#69000000</color> |
||||||
|
|
||||||
|
<color name="colorPrimary">@color/md_grey_800</color> |
||||||
|
<color name="colorPrimaryDark">@color/md_grey_900</color> |
||||||
|
<color name="colorAccent">@color/md_grey_100</color> |
||||||
|
|
||||||
|
<color name="transparent30">#30ffffff</color> |
||||||
|
|
||||||
|
<color name="bg_divider_line">#363636</color> |
||||||
|
<color name="btn_bg_press">#804D4D4D</color> |
||||||
|
<color name="btn_bg_press_2">#80686868</color> |
||||||
|
<color name="btn_bg_press_tp">#88111111</color> |
||||||
|
<color name="darker_gray">#66666666</color> |
||||||
|
|
||||||
|
<color name="tv_btn_normal_black">#737373</color> |
||||||
|
<color name="tv_btn_press_black">#565656</color> |
||||||
|
|
||||||
|
<color name="tv_text_default">#ffffffff</color> |
||||||
|
<color name="tv_text_secondary">#e5ffffff</color> |
||||||
|
<color name="tv_text_summary">#b3ffffff</color> |
||||||
|
<color name="menu_color_default">#b7b7b7</color> |
||||||
|
|
||||||
|
|
||||||
|
<color name="tv_text_button_nor">#303030</color> |
||||||
|
|
||||||
|
<!--statusBarBackground--> |
||||||
|
<color name="navigation_bar_bag">#222222</color> |
||||||
|
</resources> |
@ -0,0 +1,19 @@ |
|||||||
|
<resources> |
||||||
|
|
||||||
|
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Dark"> |
||||||
|
<item name="overlapAnchor">false</item> |
||||||
|
<item name="colorAccent">@color/md_grey_100</item> |
||||||
|
</style> |
||||||
|
|
||||||
|
<style name="Style.Shadow.Top" parent="android:Widget"> |
||||||
|
<item name="android:layout_width">match_parent</item> |
||||||
|
<item name="android:layout_height">@dimen/shadow_height</item> |
||||||
|
<item name="android:background">@drawable/bg_shadow_top_night</item> |
||||||
|
</style> |
||||||
|
|
||||||
|
<style name="Style.Shadow.Bottom" parent="android:Widget"> |
||||||
|
<item name="android:layout_width">match_parent</item> |
||||||
|
<item name="android:layout_height">@dimen/shadow_height</item> |
||||||
|
<item name="android:background">@drawable/bg_shadow_bottom_night</item> |
||||||
|
</style> |
||||||
|
</resources> |
@ -0,0 +1,338 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<resources> |
||||||
|
|
||||||
|
<!-- Google's Material Design colors from |
||||||
|
https://www.google.com/design/spec/style/color.html#color-color-palette --> |
||||||
|
|
||||||
|
<!-- Items Light --> |
||||||
|
<color name="md_light_background">@color/md_grey_50</color> |
||||||
|
<!-- 12% --> |
||||||
|
<color name="md_light_dividers">#1F000000</color> |
||||||
|
<!-- 38% --> |
||||||
|
<color name="md_light_disabled">#61000000</color> |
||||||
|
<!-- 54% --> |
||||||
|
<color name="md_light_secondary">#8A000000</color> |
||||||
|
<color name="md_light_primary_icon">#8A000000</color> |
||||||
|
<!-- 87% --> |
||||||
|
<color name="md_light_primary_text">#DE000000</color> |
||||||
|
<!-- other specifications --> |
||||||
|
<color name="md_light_statusbar">@color/md_grey_300</color> |
||||||
|
<color name="md_light_appbar">@color/md_grey_100</color> |
||||||
|
<color name="md_light_cards">@color/md_white_1000</color> |
||||||
|
<color name="md_light_dialogs">@color/md_white_1000</color> |
||||||
|
|
||||||
|
<!-- Items Dark --> |
||||||
|
<color name="md_dark_background">@color/md_grey_850</color> |
||||||
|
<!-- 12% --> |
||||||
|
<color name="md_dark_dividers">#1FFFFFFF</color> |
||||||
|
<!-- 30% --> |
||||||
|
<color name="md_dark_disabled">#4DFFFFFF</color> |
||||||
|
<!-- 70% --> |
||||||
|
<color name="md_dark_secondary">#B3FFFFFF</color> |
||||||
|
<color name="md_dark_primary_icon">#B3FFFFFF</color> |
||||||
|
<!-- 100% --> |
||||||
|
<color name="md_dark_primary_text">#FFFFFFFF</color> |
||||||
|
<!-- other specifications --> |
||||||
|
<color name="md_dark_statusbar">@color/md_black_1000</color> |
||||||
|
<color name="md_dark_appbar">@color/md_grey_900</color> |
||||||
|
<color name="md_dark_cards">@color/md_grey_800</color> |
||||||
|
<color name="md_dark_dialogs">@color/md_grey_800</color> |
||||||
|
|
||||||
|
<!-- Red --> |
||||||
|
<color name="md_red_50">#FFEBEE</color> |
||||||
|
<color name="md_red_100">#FFCDD2</color> |
||||||
|
<color name="md_red_200">#EF9A9A</color> |
||||||
|
<color name="md_red_300">#E57373</color> |
||||||
|
<color name="md_red_400">#EF5350</color> |
||||||
|
<color name="md_red_500">#F44336</color> |
||||||
|
<color name="md_red_600">#E53935</color> |
||||||
|
<color name="md_red_700">#D32F2F</color> |
||||||
|
<color name="md_red_800">#C62828</color> |
||||||
|
<color name="md_red_900">#B71C1C</color> |
||||||
|
<color name="md_red_A100">#FF8A80</color> |
||||||
|
<color name="md_red_A200">#FF5252</color> |
||||||
|
<color name="md_red_A400">#FF1744</color> |
||||||
|
<color name="md_red_A700">#D50000</color> |
||||||
|
|
||||||
|
<!-- Pink --> |
||||||
|
<color name="md_pink_50">#FCE4EC</color> |
||||||
|
<color name="md_pink_100">#F8BBD0</color> |
||||||
|
<color name="md_pink_200">#F48FB1</color> |
||||||
|
<color name="md_pink_300">#F06292</color> |
||||||
|
<color name="md_pink_400">#EC407A</color> |
||||||
|
<color name="md_pink_500">#E91E63</color> |
||||||
|
<color name="md_pink_600">#D81B60</color> |
||||||
|
<color name="md_pink_700">#C2185B</color> |
||||||
|
<color name="md_pink_800">#AD1457</color> |
||||||
|
<color name="md_pink_900">#880E4F</color> |
||||||
|
<color name="md_pink_A100">#FF80AB</color> |
||||||
|
<color name="md_pink_A200">#FF4081</color> |
||||||
|
<color name="md_pink_A400">#F50057</color> |
||||||
|
<color name="md_pink_A700">#C51162</color> |
||||||
|
|
||||||
|
<!-- Purple --> |
||||||
|
<color name="md_purple_50">#F3E5F5</color> |
||||||
|
<color name="md_purple_100">#E1BEE7</color> |
||||||
|
<color name="md_purple_200">#CE93D8</color> |
||||||
|
<color name="md_purple_300">#BA68C8</color> |
||||||
|
<color name="md_purple_400">#AB47BC</color> |
||||||
|
<color name="md_purple_500">#9C27B0</color> |
||||||
|
<color name="md_purple_600">#8E24AA</color> |
||||||
|
<color name="md_purple_700">#7B1FA2</color> |
||||||
|
<color name="md_purple_800">#6A1B9A</color> |
||||||
|
<color name="md_purple_900">#4A148C</color> |
||||||
|
<color name="md_purple_A100">#EA80FC</color> |
||||||
|
<color name="md_purple_A200">#E040FB</color> |
||||||
|
<color name="md_purple_A400">#D500F9</color> |
||||||
|
<color name="md_purple_A700">#AA00FF</color> |
||||||
|
|
||||||
|
<!-- Deep Purple --> |
||||||
|
<color name="md_deep_purple_50">#EDE7F6</color> |
||||||
|
<color name="md_deep_purple_100">#D1C4E9</color> |
||||||
|
<color name="md_deep_purple_200">#B39DDB</color> |
||||||
|
<color name="md_deep_purple_300">#9575CD</color> |
||||||
|
<color name="md_deep_purple_400">#7E57C2</color> |
||||||
|
<color name="md_deep_purple_500">#673AB7</color> |
||||||
|
<color name="md_deep_purple_600">#5E35B1</color> |
||||||
|
<color name="md_deep_purple_700">#512DA8</color> |
||||||
|
<color name="md_deep_purple_800">#4527A0</color> |
||||||
|
<color name="md_deep_purple_900">#311B92</color> |
||||||
|
<color name="md_deep_purple_A100">#B388FF</color> |
||||||
|
<color name="md_deep_purple_A200">#7C4DFF</color> |
||||||
|
<color name="md_deep_purple_A400">#651FFF</color> |
||||||
|
<color name="md_deep_purple_A700">#6200EA</color> |
||||||
|
|
||||||
|
<!-- Indigo --> |
||||||
|
<color name="md_indigo_50">#E8EAF6</color> |
||||||
|
<color name="md_indigo_100">#C5CAE9</color> |
||||||
|
<color name="md_indigo_200">#9FA8DA</color> |
||||||
|
<color name="md_indigo_300">#7986CB</color> |
||||||
|
<color name="md_indigo_400">#5C6BC0</color> |
||||||
|
<color name="md_indigo_500">#3F51B5</color> |
||||||
|
<color name="md_indigo_600">#3949AB</color> |
||||||
|
<color name="md_indigo_700">#303F9F</color> |
||||||
|
<color name="md_indigo_800">#283593</color> |
||||||
|
<color name="md_indigo_900">#1A237E</color> |
||||||
|
<color name="md_indigo_A100">#8C9EFF</color> |
||||||
|
<color name="md_indigo_A200">#536DFE</color> |
||||||
|
<color name="md_indigo_A400">#3D5AFE</color> |
||||||
|
<color name="md_indigo_A700">#304FFE</color> |
||||||
|
|
||||||
|
<!-- Blue --> |
||||||
|
<color name="md_blue_50">#E3F2FD</color> |
||||||
|
<color name="md_blue_100">#BBDEFB</color> |
||||||
|
<color name="md_blue_200">#90CAF9</color> |
||||||
|
<color name="md_blue_300">#64B5F6</color> |
||||||
|
<color name="md_blue_400">#42A5F5</color> |
||||||
|
<color name="md_blue_500">#2196F3</color> |
||||||
|
<color name="md_blue_600">#1E88E5</color> |
||||||
|
<color name="md_blue_700">#1976D2</color> |
||||||
|
<color name="md_blue_800">#1565C0</color> |
||||||
|
<color name="md_blue_900">#0D47A1</color> |
||||||
|
<color name="md_blue_A100">#82B1FF</color> |
||||||
|
<color name="md_blue_A200">#448AFF</color> |
||||||
|
<color name="md_blue_A400">#2979FF</color> |
||||||
|
<color name="md_blue_A700">#2962FF</color> |
||||||
|
|
||||||
|
<!-- Light Blue --> |
||||||
|
<color name="md_light_blue_50">#E1F5FE</color> |
||||||
|
<color name="md_light_blue_100">#B3E5FC</color> |
||||||
|
<color name="md_light_blue_200">#81D4FA</color> |
||||||
|
<color name="md_light_blue_300">#4FC3F7</color> |
||||||
|
<color name="md_light_blue_400">#29B6F6</color> |
||||||
|
<color name="md_light_blue_500">#03A9F4</color> |
||||||
|
<color name="md_light_blue_600">#039BE5</color> |
||||||
|
<color name="md_light_blue_700">#0288D1</color> |
||||||
|
<color name="md_light_blue_800">#0277BD</color> |
||||||
|
<color name="md_light_blue_900">#01579B</color> |
||||||
|
<color name="md_light_blue_A100">#80D8FF</color> |
||||||
|
<color name="md_light_blue_A200">#40C4FF</color> |
||||||
|
<color name="md_light_blue_A400">#00B0FF</color> |
||||||
|
<color name="md_light_blue_A700">#0091EA</color> |
||||||
|
|
||||||
|
<!-- Cyan --> |
||||||
|
<color name="md_cyan_50">#E0F7FA</color> |
||||||
|
<color name="md_cyan_100">#B2EBF2</color> |
||||||
|
<color name="md_cyan_200">#80DEEA</color> |
||||||
|
<color name="md_cyan_300">#4DD0E1</color> |
||||||
|
<color name="md_cyan_400">#26C6DA</color> |
||||||
|
<color name="md_cyan_500">#00BCD4</color> |
||||||
|
<color name="md_cyan_600">#00ACC1</color> |
||||||
|
<color name="md_cyan_700">#0097A7</color> |
||||||
|
<color name="md_cyan_800">#00838F</color> |
||||||
|
<color name="md_cyan_900">#006064</color> |
||||||
|
<color name="md_cyan_A100">#84FFFF</color> |
||||||
|
<color name="md_cyan_A200">#18FFFF</color> |
||||||
|
<color name="md_cyan_A400">#00E5FF</color> |
||||||
|
<color name="md_cyan_A700">#00B8D4</color> |
||||||
|
|
||||||
|
<!-- Teal --> |
||||||
|
<color name="md_teal_50">#E0F2F1</color> |
||||||
|
<color name="md_teal_100">#B2DFDB</color> |
||||||
|
<color name="md_teal_200">#80CBC4</color> |
||||||
|
<color name="md_teal_300">#4DB6AC</color> |
||||||
|
<color name="md_teal_400">#26A69A</color> |
||||||
|
<color name="md_teal_500">#009688</color> |
||||||
|
<color name="md_teal_600">#00897B</color> |
||||||
|
<color name="md_teal_700">#00796B</color> |
||||||
|
<color name="md_teal_800">#00695C</color> |
||||||
|
<color name="md_teal_900">#004D40</color> |
||||||
|
<color name="md_teal_A100">#A7FFEB</color> |
||||||
|
<color name="md_teal_A200">#64FFDA</color> |
||||||
|
<color name="md_teal_A400">#1DE9B6</color> |
||||||
|
<color name="md_teal_A700">#00BFA5</color> |
||||||
|
|
||||||
|
<!-- Green --> |
||||||
|
<color name="md_green_50">#E8F5E9</color> |
||||||
|
<color name="md_green_100">#C8E6C9</color> |
||||||
|
<color name="md_green_200">#A5D6A7</color> |
||||||
|
<color name="md_green_300">#81C784</color> |
||||||
|
<color name="md_green_400">#66BB6A</color> |
||||||
|
<color name="md_green_500">#4CAF50</color> |
||||||
|
<color name="md_green_600">#43A047</color> |
||||||
|
<color name="md_green_700">#388E3C</color> |
||||||
|
<color name="md_green_800">#2E7D32</color> |
||||||
|
<color name="md_green_900">#1B5E20</color> |
||||||
|
<color name="md_green_A100">#B9F6CA</color> |
||||||
|
<color name="md_green_A200">#69F0AE</color> |
||||||
|
<color name="md_green_A400">#00E676</color> |
||||||
|
<color name="md_green_A700">#00C853</color> |
||||||
|
|
||||||
|
<!-- Light Green --> |
||||||
|
<color name="md_light_green_50">#F1F8E9</color> |
||||||
|
<color name="md_light_green_100">#DCEDC8</color> |
||||||
|
<color name="md_light_green_200">#C5E1A5</color> |
||||||
|
<color name="md_light_green_300">#AED581</color> |
||||||
|
<color name="md_light_green_400">#9CCC65</color> |
||||||
|
<color name="md_light_green_500">#8BC34A</color> |
||||||
|
<color name="md_light_green_600">#7CB342</color> |
||||||
|
<color name="md_light_green_700">#689F38</color> |
||||||
|
<color name="md_light_green_800">#558B2F</color> |
||||||
|
<color name="md_light_green_900">#33691E</color> |
||||||
|
<color name="md_light_green_A100">#CCFF90</color> |
||||||
|
<color name="md_light_green_A200">#B2FF59</color> |
||||||
|
<color name="md_light_green_A400">#76FF03</color> |
||||||
|
<color name="md_light_green_A700">#64DD17</color> |
||||||
|
|
||||||
|
<!-- Lime --> |
||||||
|
<color name="md_lime_50">#F9FBE7</color> |
||||||
|
<color name="md_lime_100">#F0F4C3</color> |
||||||
|
<color name="md_lime_200">#E6EE9C</color> |
||||||
|
<color name="md_lime_300">#DCE775</color> |
||||||
|
<color name="md_lime_400">#D4E157</color> |
||||||
|
<color name="md_lime_500">#CDDC39</color> |
||||||
|
<color name="md_lime_600">#C0CA33</color> |
||||||
|
<color name="md_lime_700">#AFB42B</color> |
||||||
|
<color name="md_lime_800">#9E9D24</color> |
||||||
|
<color name="md_lime_900">#827717</color> |
||||||
|
<color name="md_lime_A100">#F4FF81</color> |
||||||
|
<color name="md_lime_A200">#EEFF41</color> |
||||||
|
<color name="md_lime_A400">#C6FF00</color> |
||||||
|
<color name="md_lime_A700">#AEEA00</color> |
||||||
|
|
||||||
|
<!-- Yellow --> |
||||||
|
<color name="md_yellow_50">#FFFDE7</color> |
||||||
|
<color name="md_yellow_100">#FFF9C4</color> |
||||||
|
<color name="md_yellow_200">#FFF59D</color> |
||||||
|
<color name="md_yellow_300">#FFF176</color> |
||||||
|
<color name="md_yellow_400">#FFEE58</color> |
||||||
|
<color name="md_yellow_500">#FFEB3B</color> |
||||||
|
<color name="md_yellow_600">#FDD835</color> |
||||||
|
<color name="md_yellow_700">#FBC02D</color> |
||||||
|
<color name="md_yellow_800">#F9A825</color> |
||||||
|
<color name="md_yellow_900">#F57F17</color> |
||||||
|
<color name="md_yellow_A100">#FFFF8D</color> |
||||||
|
<color name="md_yellow_A200">#FFFF00</color> |
||||||
|
<color name="md_yellow_A400">#FFEA00</color> |
||||||
|
<color name="md_yellow_A700">#FFD600</color> |
||||||
|
|
||||||
|
<!-- Amber --> |
||||||
|
<color name="md_amber_50">#FFF8E1</color> |
||||||
|
<color name="md_amber_100">#FFECB3</color> |
||||||
|
<color name="md_amber_200">#FFE082</color> |
||||||
|
<color name="md_amber_300">#FFD54F</color> |
||||||
|
<color name="md_amber_400">#FFCA28</color> |
||||||
|
<color name="md_amber_500">#FFC107</color> |
||||||
|
<color name="md_amber_600">#FFB300</color> |
||||||
|
<color name="md_amber_700">#FFA000</color> |
||||||
|
<color name="md_amber_800">#FF8F00</color> |
||||||
|
<color name="md_amber_900">#FF6F00</color> |
||||||
|
<color name="md_amber_A100">#FFE57F</color> |
||||||
|
<color name="md_amber_A200">#FFD740</color> |
||||||
|
<color name="md_amber_A400">#FFC400</color> |
||||||
|
<color name="md_amber_A700">#FFAB00</color> |
||||||
|
|
||||||
|
<!-- Orange --> |
||||||
|
<color name="md_orange_50">#FFF3E0</color> |
||||||
|
<color name="md_orange_100">#FFE0B2</color> |
||||||
|
<color name="md_orange_200">#FFCC80</color> |
||||||
|
<color name="md_orange_300">#FFB74D</color> |
||||||
|
<color name="md_orange_400">#FFA726</color> |
||||||
|
<color name="md_orange_500">#FF9800</color> |
||||||
|
<color name="md_orange_600">#FB8C00</color> |
||||||
|
<color name="md_orange_700">#F57C00</color> |
||||||
|
<color name="md_orange_800">#EF6C00</color> |
||||||
|
<color name="md_orange_900">#E65100</color> |
||||||
|
<color name="md_orange_A100">#FFD180</color> |
||||||
|
<color name="md_orange_A200">#FFAB40</color> |
||||||
|
<color name="md_orange_A400">#FF9100</color> |
||||||
|
<color name="md_orange_A700">#FF6D00</color> |
||||||
|
|
||||||
|
<!-- Deep Orange --> |
||||||
|
<color name="md_deep_orange_50">#FBE9E7</color> |
||||||
|
<color name="md_deep_orange_100">#FFCCBC</color> |
||||||
|
<color name="md_deep_orange_200">#FFAB91</color> |
||||||
|
<color name="md_deep_orange_300">#FF8A65</color> |
||||||
|
<color name="md_deep_orange_400">#FF7043</color> |
||||||
|
<color name="md_deep_orange_500">#FF5722</color> |
||||||
|
<color name="md_deep_orange_600">#F4511E</color> |
||||||
|
<color name="md_deep_orange_700">#E64A19</color> |
||||||
|
<color name="md_deep_orange_800">#D84315</color> |
||||||
|
<color name="md_deep_orange_900">#BF360C</color> |
||||||
|
<color name="md_deep_orange_A100">#FF9E80</color> |
||||||
|
<color name="md_deep_orange_A200">#FF6E40</color> |
||||||
|
<color name="md_deep_orange_A400">#FF3D00</color> |
||||||
|
<color name="md_deep_orange_A700">#DD2C00</color> |
||||||
|
|
||||||
|
<!-- Brown --> |
||||||
|
<color name="md_brown_50">#EFEBE9</color> |
||||||
|
<color name="md_brown_100">#D7CCC8</color> |
||||||
|
<color name="md_brown_200">#BCAAA4</color> |
||||||
|
<color name="md_brown_300">#A1887F</color> |
||||||
|
<color name="md_brown_400">#8D6E63</color> |
||||||
|
<color name="md_brown_500">#795548</color> |
||||||
|
<color name="md_brown_600">#6D4C41</color> |
||||||
|
<color name="md_brown_700">#5D4037</color> |
||||||
|
<color name="md_brown_800">#4E342E</color> |
||||||
|
<color name="md_brown_900">#3E2723</color> |
||||||
|
|
||||||
|
<!-- Grey --> |
||||||
|
<color name="md_grey_50">#FAFAFA</color> |
||||||
|
<color name="md_grey_100">#F5F5F5</color> |
||||||
|
<color name="md_grey_200">#EEEEEE</color> |
||||||
|
<color name="md_grey_300">#E0E0E0</color> |
||||||
|
<color name="md_grey_400">#BDBDBD</color> |
||||||
|
<color name="md_grey_500">#9E9E9E</color> |
||||||
|
<color name="md_grey_600">#757575</color> |
||||||
|
<color name="md_grey_700">#616161</color> |
||||||
|
<color name="md_grey_800">#424242</color> |
||||||
|
<color name="md_grey_850">#303030</color> |
||||||
|
<color name="md_grey_900">#212121</color> |
||||||
|
|
||||||
|
<!-- Blue Grey --> |
||||||
|
<color name="md_blue_grey_50">#ECEFF1</color> |
||||||
|
<color name="md_blue_grey_100">#CFD8DC</color> |
||||||
|
<color name="md_blue_grey_200">#B0BEC5</color> |
||||||
|
<color name="md_blue_grey_300">#90A4AE</color> |
||||||
|
<color name="md_blue_grey_400">#78909C</color> |
||||||
|
<color name="md_blue_grey_500">#607D8B</color> |
||||||
|
<color name="md_blue_grey_600">#546E7A</color> |
||||||
|
<color name="md_blue_grey_700">#455A64</color> |
||||||
|
<color name="md_blue_grey_800">#37474F</color> |
||||||
|
<color name="md_blue_grey_900">#263238</color> |
||||||
|
|
||||||
|
<!-- Black & White --> |
||||||
|
<color name="md_black_1000">#000000</color> |
||||||
|
<color name="md_white_1000">#FFFFFF</color> |
||||||
|
|
||||||
|
</resources> |
Loading…
Reference in new issue