Skip to content

Commit

Permalink
Merge pull request #6 from ozodrukh/patch-1
Browse files Browse the repository at this point in the history
- setTint reportedly working
- Allow reflection method caching
- Fixes MethodNotFoundException on Lollipop
  • Loading branch information
eveliotc committed Dec 30, 2014
2 parents 12a11a7 + f56127c commit df4c821
Showing 1 changed file with 35 additions and 14 deletions.
49 changes: 35 additions & 14 deletions library/src/main/java/com/telly/mrvector/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,18 @@
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.v4.util.SimpleArrayMap;
import android.util.Log;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import static android.graphics.PorterDuff.Mode;
import static android.graphics.PorterDuff.Mode.SRC_IN;
import static android.os.Build.VERSION.SDK_INT;
import static android.os.Build.VERSION_CODES.HONEYCOMB;
import static android.os.Build.VERSION_CODES.LOLLIPOP;
import static android.util.LayoutDirection.LTR;
import static com.telly.mrvector.VectorDrawable.LOGTAG;
Expand All @@ -40,21 +47,28 @@ public class Utils {
*/
static final Mode DEFAULT_TINT_MODE = SRC_IN;
static final boolean LOLLIPOP_PLUS = SDK_INT >= LOLLIPOP;
static final boolean HONEYCOMB_PLUS = SDK_INT >= HONEYCOMB;

public static <T> T tryInvoke(Object target, String methodName, Object... args) {
final int argsCount = args == null ? 0 : args.length;
Class<?>[] argTypes = new Class<?>[argsCount];
for (int i = 0; i < argsCount; i++) {
argTypes[i] = args[i].getClass();
}
static SimpleArrayMap<String, Method> sCachedMethods = new SimpleArrayMap<>();

return tryInvoke(target, methodName, argTypes, args);
}
final static Class[] INT_ARG = {int.class};
final static Class[] MODE_ARG = {Mode.class};
final static Class[] EMPTY_ARG = {};

@SuppressWarnings("unchecked")
public static <T> T tryInvoke(Object target, String methodName, Class<?>[] argTypes,
Object... args) {

try {
return (T) target.getClass().getDeclaredMethod(methodName, argTypes).invoke(target, args);
Method method = sCachedMethods.get(methodName);
if(method != null){
return (T) method.invoke(target, args);
}

method = target.getClass().getDeclaredMethod(methodName, argTypes);
sCachedMethods.put(methodName, method);

return (T) method.invoke(target, args);
} catch (Exception pokemon) {
Log.e(LOGTAG, "Unable to invoke " + methodName + " on " + target, pokemon);
}
Expand All @@ -63,7 +77,7 @@ public static <T> T tryInvoke(Object target, String methodName, Class<?>[] argTy
}

static int getLayoutDirection(Drawable drawable) {
final Integer layoutDirection = tryInvoke(drawable, "getLayoutDirection", (Object[])null);
final Integer layoutDirection = tryInvoke(drawable, "getLayoutDirection", EMPTY_ARG);
return layoutDirection == null ? LTR : layoutDirection.intValue();
}

Expand All @@ -80,8 +94,14 @@ static Mode parseTintMode(int value, Mode defaultMode) {
case 9: return Mode.SRC_ATOP;
case 14: return Mode.MULTIPLY;
case 15: return Mode.SCREEN;
case 16: return Mode.ADD;
default: return defaultMode;

case 16:
if(HONEYCOMB_PLUS) {
return Mode.ADD;
}

default:
return defaultMode;
}
}

Expand All @@ -96,12 +116,13 @@ static PorterDuffColorFilter updateTintFilter(Drawable drawable, PorterDuffColor
}

final int color = tint.getColorForState(drawable.getState(), Color.TRANSPARENT);

if (tintFilter == null || !LOLLIPOP_PLUS) { // TODO worth caching them?
return new PorterDuffColorFilter(color, tintMode);
}

tryInvoke(tintFilter, "setColor", color);
tryInvoke(tintFilter, "setMode", tintMode);
tryInvoke(tintFilter, "setColor", INT_ARG, color);
tryInvoke(tintFilter, "setMode", MODE_ARG, tintMode);
return tintFilter;
}

Expand Down

0 comments on commit df4c821

Please sign in to comment.