-
Notifications
You must be signed in to change notification settings - Fork 6.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for decoding non-Bitmap drawables using Resources.
As a fallback for drawables that we either can’t obtain an InputStream for or can’t decode as Bitmaps, Glide will now also call Resources#getDrawable with the given resource id. Fixes #350.
- Loading branch information
Showing
5 changed files
with
151 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
49 changes: 49 additions & 0 deletions
49
library/src/main/java/com/bumptech/glide/load/resource/drawable/DrawableDecoderCompat.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package com.bumptech.glide.load.resource.drawable; | ||
|
||
import android.content.Context; | ||
import android.content.res.Resources; | ||
import android.content.res.Resources.Theme; | ||
import android.graphics.drawable.Drawable; | ||
import android.support.annotation.DrawableRes; | ||
import android.support.annotation.Nullable; | ||
import android.support.v4.content.res.ResourcesCompat; | ||
import android.support.v7.content.res.AppCompatResources; | ||
|
||
/** | ||
* Handles decoding Drawables with the v7 support library if present and falling back to the v4 | ||
* support library otherwise. | ||
*/ | ||
public final class DrawableDecoderCompat { | ||
private static volatile boolean shouldCallAppCompatResources = true; | ||
private DrawableDecoderCompat() { | ||
// Utility class. | ||
} | ||
|
||
/** | ||
* Loads a Drawable using {@link AppCompatResources} if available and {@link ResourcesCompat} | ||
* otherwise, depending on whether or not the v7 support library is included in the application. | ||
*/ | ||
public static Drawable getDrawable(Context context, @DrawableRes int id, @Nullable Theme theme) { | ||
try { | ||
// Race conditions may cause us to attempt to load using v7 more than once. That's ok since | ||
// this check is a modest optimization and the output will be correct anyway. | ||
if (shouldCallAppCompatResources) { | ||
return loadDrawableV7(context, id); | ||
} | ||
} catch (NoClassDefFoundError error) { | ||
shouldCallAppCompatResources = false; | ||
} | ||
|
||
return loadDrawableV4(context, id, theme != null ? theme : context.getTheme()); | ||
} | ||
|
||
private static Drawable loadDrawableV7(Context context, @DrawableRes int id) { | ||
return AppCompatResources.getDrawable(context, id); | ||
} | ||
|
||
private static Drawable loadDrawableV4( | ||
Context context, @DrawableRes int id, @Nullable Theme theme) { | ||
Resources resources = context.getResources(); | ||
return ResourcesCompat.getDrawable(resources, id, theme); | ||
} | ||
} |
70 changes: 70 additions & 0 deletions
70
library/src/main/java/com/bumptech/glide/load/resource/drawable/ResourceDrawableDecoder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package com.bumptech.glide.load.resource.drawable; | ||
|
||
import android.content.ContentResolver; | ||
import android.content.Context; | ||
import android.graphics.drawable.Drawable; | ||
import android.net.Uri; | ||
import android.support.annotation.Nullable; | ||
import com.bumptech.glide.load.Options; | ||
import com.bumptech.glide.load.ResourceDecoder; | ||
import com.bumptech.glide.load.engine.Resource; | ||
import java.io.IOException; | ||
import java.util.List; | ||
|
||
/** | ||
* Decodes {@link Drawable}s given resource {@link Uri}s in the form | ||
* android.resource://<package_name>/<type>/<name>. | ||
*/ | ||
public class ResourceDrawableDecoder implements ResourceDecoder<Uri, Drawable> { | ||
private static final int EXPECTED_PATH_SEGMENTS = 2; | ||
private static final int TYPE_PATH_SEGMENT_INDEX = 0; | ||
private static final int NAME_PATH_SEGMENT_INDEX = 1; | ||
|
||
private final Context context; | ||
|
||
public ResourceDrawableDecoder(Context context) { | ||
this.context = context.getApplicationContext(); | ||
} | ||
|
||
@Override | ||
public boolean handles(Uri source, Options options) throws IOException { | ||
return source.getScheme().equals(ContentResolver.SCHEME_ANDROID_RESOURCE); | ||
} | ||
|
||
@Nullable | ||
@Override | ||
public Resource<Drawable> decode(Uri source, int width, int height, Options options) | ||
throws IOException { | ||
// Parsing is based on the logic in ResourceLoader/the android framework that constructs | ||
// resource Uris. | ||
List<String> segments = source.getPathSegments(); | ||
if (segments.size() != EXPECTED_PATH_SEGMENTS) { | ||
throw new IOException("Unexpected path segments for: " + source + " segments: " + segments); | ||
} | ||
String packageName = source.getAuthority(); | ||
String typeName = segments.get(TYPE_PATH_SEGMENT_INDEX); | ||
String resourceName = segments.get(NAME_PATH_SEGMENT_INDEX); | ||
int id = context.getResources().getIdentifier(resourceName, typeName, packageName); | ||
Drawable drawable = DrawableDecoderCompat.getDrawable(context, id, null /*theme*/); | ||
if (drawable == null) { | ||
throw new IOException("ContextCompat#getDrawable returned null for: " + source); | ||
} | ||
return new DrawableResource<Drawable>(drawable) { | ||
@SuppressWarnings("unchecked") | ||
@Override | ||
public Class<Drawable> getResourceClass() { | ||
return (Class<Drawable>) drawable.getClass(); | ||
} | ||
|
||
@Override | ||
public int getSize() { | ||
return 1; | ||
} | ||
|
||
@Override | ||
public void recycle() { | ||
// Do nothing. | ||
} | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters