Repository navigation
Use ContextCompat to retrieve drawables #1422
Description
Activity
Seems reasonable. Wanna contribute?
Would love to take care of it. Just no time right now. Keep it here for tracking, first.
Having that said, @WonderCsabo how could one actually check if the class is available? We'd have to add the "compile" scope into the annotation processing scope (
apt) and check there. Is that even possible?We can just check whether it is on the classpath and that is working already. We do not know anything about whether it will be really packaged into the app or not, but we expect it will be. We already do this kind of check when we generate the
Activitybuilders.@ened i forgot that we should handle the cases when
ContextCompatis not available.minSdkVersion => 21 && ContextCompat is not available:
backgroundDrawable = context.getDrawable();
minSdkVersion < 21 && compileSdkVersion >=21 && ContextCompat is not available:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { backgroundDrawable = context.getDrawable(); } else { backgroundDrawable = resources_.getDrawable(); }
Can you implement that?
Would that check be done during compile time or in a runtime switch? Probably generate the code like you showed it, right?
Yeah generate that code, the compile time conditional is in italic.
Ok cool. Is there another component that's doing such a check?
- You can look at ActivityIntentBuilder. Minsdkversion is available in our AndroidManifest API, compileSdkVersion is not, so you have to check that the Context.getDrawable method is available or not (like ActivityIntentBuilder.hasActivityOptions).
Now I got something like this:
private void init_(Bundle savedInstanceState) { if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { myDrawable = this.getDrawable(drawable.myDrawable); } else { myDrawable = resources_.getDrawable(drawable.myDrawable); } Resources resources_ = this.getResources(); }But I can't find out why the resources_ variable is initialized AFTER the usage. :)
Heres the code that generates it:
} else if (element.getAnnotation(DrawableRes.class) != null && !hasContextWithGetDrawableMethod() && hasGetDrawableInContext() && !hasContextCompatInClasspath()) { createCallWithIfGuard(holder, ref(fieldName), methodBody, idRef);private void createCallWithIfGuard(EComponentHolder holder, JFieldRef ref, JBlock methodBody, JFieldRef idRef) { JConditional guardIf = methodBody._if(holder.classes().BUILD_VERSION.staticRef("SDK_INT").gte(holder.classes().BUILD_VERSION_CODES.staticRef("LOLLIPOP"))); JBlock ifBlock = guardIf._then(); ifBlock.assign(ref, holder.getContextRef().invoke("getDrawable").arg(idRef)); JBlock elseBlock = guardIf._else(); elseBlock.assign(ref, holder.getResourcesRef().invoke("getDrawable").arg(idRef)); }@WonderCsabo Spontaneous idea?
OK I found it. Just had to get a hold of the resourcesRef earlier. PR coming. :)
Given I'm injecting a drawable into my fragment like that:
Then Android Annotations generates this code:
Which then generates this compiler warning for
targetSdk=22builds:Instead, AndroidAnnoations should, given the class ContextCompat is available, generate this:
Benefits: