package net.xpece.material.navigationdrawer.internal; import android.annotation.TargetApi; import android.content.Context; import android.content.res.TypedArray; import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.StateListDrawable; import android.os.Build; import android.support.annotation.AttrRes; import android.support.annotation.ColorRes; import android.support.annotation.DrawableRes; import android.util.Log; import android.util.StateSet; import android.util.TypedValue; import android.view.View; import android.view.ViewTreeObserver; import net.xpece.material.navigationdrawer.BuildConfig; import net.xpece.material.navigationdrawer.R; /** * Created by pechanecjr on 14. 12. 2014. */ public class Utils { public static final int APPCOMPAT_ATTR_SELECTABLE_ITEM_BACKGROUND; public static final int APPCOMPAT_ATTR_ACTIVATED_BACKGROUND_INDICATOR; static { final String clsName = "android.support.v7.appcompat.R$attr"; int selectableItemBackground; int activatedBackgroundIndicator; try { selectableItemBackground = Class.forName(clsName).getField("selectableItemBackground").getInt(null); } catch (Exception e) { selectableItemBackground = 0; } try { activatedBackgroundIndicator = Class.forName(clsName).getField("colorControlActivated").getInt(null); } catch (Exception e) { activatedBackgroundIndicator = 0; } APPCOMPAT_ATTR_SELECTABLE_ITEM_BACKGROUND = selectableItemBackground; APPCOMPAT_ATTR_ACTIVATED_BACKGROUND_INDICATOR = activatedBackgroundIndicator; } private Utils() { } // @TargetApi(21) // public static void setElevation(View view, float elevation) { // if (Build.VERSION.SDK_INT >= 21) view.setElevation(elevation); // } public static Drawable createRoundRect(Context context, int color, int cornerDp) { GradientDrawable gd = new GradientDrawable(); gd.setColor(color); gd.setCornerRadius(Utils.dpToPixel(context, cornerDp)); return gd; } public static int dpToPixelSize(Context context, int dp) { return Math.round(0.5f + dpToPixel(context, dp)); } public static int dpToPixelOffset(Context context, int dp) { return (int) dpToPixel(context, dp); } public static float dpToPixel(Context context, int dp) { return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics()); } /** * Sauce: http://stackoverflow.com/questions/1855884/determine-font-color-based-on-background-color * More sauce: http://stackoverflow.com/a/596243/2444099 * * @param background * @return */ public static int computeTextColor(Context context, int background) { int r = (background & 0xff0000) >> 16; int g = (background & 0xff00) >> 8; int b = background & 0xff; double a = computeTextColorAlgorithm2(r, g, b); // Log.w("#computeTextColor", "r=" + r + ", g=" + g + ", b=" + b + ", contrast=" + a); if ((int) (a * 100) <= 50) // light blue was so close that i just had to do this ^^ return context.getResources().getColor(R.color.mnd_text_primary_dark); else return context.getResources().getColor(R.color.mnd_text_primary_light); } private static double computeTextColorAlgorithm0(int r, int g, int b) { return (r / 3.0 + g / 3.0 + b / 3.0) / 255; } private static double computeTextColorAlgorithm1(int r, int g, int b) { return (0.2126 * r + 0.7152 * g + 0.0722 * b) / 255; } private static double computeTextColorAlgorithm2(int r, int g, int b) { // Counting the perceptive luminance - human eye favors green color... return (0.299 * r + 0.587 * g + 0.114 * b) / 255; } @TargetApi(Build.VERSION_CODES.HONEYCOMB) public static Drawable createActivatedDrawable(Drawable drawable, int passive, int active) { ColorFilterStateListDrawable stateful = new ColorFilterStateListDrawable(); stateful.addState(new int[]{android.R.attr.state_activated}, drawable, active); stateful.addState(StateSet.WILD_CARD, drawable, passive); return stateful; } @TargetApi(Build.VERSION_CODES.HONEYCOMB) public static Drawable createActivatedDrawable(int passive, int active) { StateListDrawable stateful = new StateListDrawable(); stateful.addState(new int[]{android.R.attr.state_activated}, new ColorDrawable(active)); stateful.addState(StateSet.WILD_CARD, new ColorDrawable(passive)); return stateful; } public static boolean getBoolean(Context context, @AttrRes int attr, boolean fallback) { TypedArray ta = context.obtainStyledAttributes(new int[]{attr}); try { return ta.getBoolean(0, fallback); } finally { ta.recycle(); } } public static int getColor(Context context, @AttrRes int attr, int fallback) { TypedArray ta = context.obtainStyledAttributes(new int[]{attr}); try { return ta.getColor(0, fallback); } finally { ta.recycle(); } } public static Drawable getDrawableAttr(Context context, @AttrRes int attr) { TypedArray ta = context.obtainStyledAttributes(new int[]{attr}); try { return ta.getDrawable(0); } finally { ta.recycle(); } } @TargetApi(21) @SuppressWarnings("deprecation") public static Drawable getDrawableRes(Context context, @DrawableRes int resId) { if (Build.VERSION.SDK_INT < 21) { return context.getResources().getDrawable(resId); } else { return context.getDrawable(resId); } } public static Drawable tintDrawable(Context context, @DrawableRes int drawableId, @ColorRes int colorId) { Drawable d = context.getResources().getDrawable(drawableId); int c = context.getResources().getColor(colorId); return tintDrawable(d, c); } public static Drawable tintDrawable(Drawable d, int c) { // PorterDuffColorFilter cf = COLOR_FILTER_CACHE.get(c); // if (cf == null) { // cf = new PorterDuffColorFilter(c, PorterDuff.Mode.SRC_IN); // COLOR_FILTER_CACHE.put(c, cf); // } PorterDuffColorFilter cf = new PorterDuffColorFilter(c, PorterDuff.Mode.SRC_IN); d.setColorFilter(cf); return d; } @TargetApi(16) public static void setBackground(View v, Drawable d) { if (Build.VERSION.SDK_INT >= 16) { v.setBackground(d); } else { v.setBackgroundDrawable(d); } } @TargetApi(16) public static void removeOnGlobalLayoutListener(View view, ViewTreeObserver.OnGlobalLayoutListener listener) { if (Build.VERSION.SDK_INT >= 16) { view.getViewTreeObserver().removeOnGlobalLayoutListener(listener); } else { view.getViewTreeObserver().removeGlobalOnLayoutListener(listener); } } public static int createDividerColor(Context context) { return Utils.getColor(context, android.R.attr.colorForeground, 0) & 0x1effffff; } public static int createActivatedColor(Context context) { // return Utils.getColor(context, android.R.attr.colorForeground, 0) & 0x12ffffff; return Utils.getColor(context, android.R.attr.colorForeground, 0) & 0x1effffff; } @TargetApi(Build.VERSION_CODES.HONEYCOMB) public static Drawable getSelectorDrawable(Context context) { Drawable d = null; if (APPCOMPAT_ATTR_SELECTABLE_ITEM_BACKGROUND != 0) { d = getDrawableAttr(context, APPCOMPAT_ATTR_SELECTABLE_ITEM_BACKGROUND); } if (d != null) return d; if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { return context.getResources().getDrawable(android.R.drawable.list_selector_background); } else { return getDrawableAttr(context, android.R.attr.selectableItemBackground); } } public static Drawable getActivatedDrawable(Context context) { return new ColorDrawable(createActivatedColor(context)); } /** * Sets the base elevation of this view, in pixels. */ @TargetApi(21) public static void setElevation(View view, float elevation) { if (Build.VERSION.SDK_INT >= 21) { view.setElevation(elevation); } } public static void timber(String tag, String s) { if (BuildConfig.DEBUG) Log.d(tag, s); } }