问题
I have custom ImageView for animated GIF image. i want to show GIF image, I tried but in this case it is contain url in Async instead I want to show GIF image from raw folder without using Glide. Anyone have any idea how to show image? Please guyz help to solve this problem!!!
I tried this for set raw file
new GifStaticData() {
@Override
protected void onPostExecute(Resource drawable) {
super.onPostExecute(drawable);
gifImageView.setImageResource(R.raw.earth_tilt_animation);
// Log.d(TAG, "GIF width is " + gifImageView.getGifWidth());
// Log.d(TAG, "GIF height is " + gifImageView.getGifHeight());
}
}.execute(R.raw.earth_tilt_animation);
GifStaticData.java
public class GifStaticData extends AsyncTask<Resource, Void, Resource> {
private static final String TAG = "GifDataDownloader";
@Override protected Resource doInBackground(final Resource... params) {
final Resource gifUrl = params[0];
if (gifUrl == null)
return null;
try {
// return ByteArrayHttpClient.get(gifUrl);
return gifUrl;
} catch (OutOfMemoryError e) {
Log.e(TAG, "GifDecode OOM: " + gifUrl, e);
return null;
}
}
}
GifImageView.java
public class GifImageView extends ImageView implements Runnable {
private static final String TAG = "GifDecoderView";
private GifDecoder gifDecoder;
private Bitmap tmpBitmap;
private final Handler handler = new Handler(Looper.getMainLooper());
private boolean animating;
private boolean shouldClear;
private Thread animationThread;
private OnFrameAvailable frameCallback = null;
private long framesDisplayDuration = -1L;
private OnAnimationStop animationStopCallback = null;
private final Runnable updateResults = new Runnable() {
@Override
public void run() {
if (tmpBitmap != null && !tmpBitmap.isRecycled()) {
setImageBitmap(tmpBitmap);
}
}
};
private final Runnable cleanupRunnable = new Runnable() {
@Override
public void run() {
tmpBitmap = null;
gifDecoder = null;
animationThread = null;
shouldClear = false;
}
};
public GifImageView(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
public GifImageView(final Context context) {
super(context);
}
public void setBytes(final byte[] bytes) {
gifDecoder = new GifDecoder();
try {
gifDecoder.read(bytes);
gifDecoder.advance();
} catch (final OutOfMemoryError e) {
gifDecoder = null;
Log.e(TAG, e.getMessage(), e);
return;
}
if (canStart()) {
animationThread = new Thread(this);
animationThread.start();
}
}
public long getFramesDisplayDuration() {
return framesDisplayDuration;
}
/**
* Sets custom display duration in milliseconds for the all frames. Should be called before {@link
* #startAnimation()}
*
* @param framesDisplayDuration Duration in milliseconds. Default value = -1, this property will
* be ignored and default delay from gif file will be used.
*/
public void setFramesDisplayDuration(long framesDisplayDuration) {
this.framesDisplayDuration = framesDisplayDuration;
}
public void startAnimation() {
animating = true;
if (canStart()) {
animationThread = new Thread(this);
animationThread.start();
}
}
public boolean isAnimating() {
return animating;
}
public void stopAnimation() {
animating = false;
if (animationThread != null) {
animationThread.interrupt();
animationThread = null;
}
}
public void clear() {
animating = false;
shouldClear = true;
stopAnimation();
handler.post(cleanupRunnable);
}
private boolean canStart() {
return animating && gifDecoder != null && animationThread == null;
}
public int getGifWidth() {
return gifDecoder.getWidth();
}
public int getGifHeight() {
return gifDecoder.getHeight();
}
@Override public void run() {
if (shouldClear) {
handler.post(cleanupRunnable);
return;
}
final int n = gifDecoder.getFrameCount();
do {
for (int i = 0; i < n; i++) {
if (!animating) {
break;
}
//milliseconds spent on frame decode
long frameDecodeTime = 0;
try {
long before = System.nanoTime();
tmpBitmap = gifDecoder.getNextFrame();
frameDecodeTime = (System.nanoTime() - before) / 1000000;
if (frameCallback != null) {
tmpBitmap = frameCallback.onFrameAvailable(tmpBitmap);
}
if (!animating) {
break;
}
handler.post(updateResults);
} catch (final ArrayIndexOutOfBoundsException | IllegalArgumentException e) {
Log.w(TAG, e);
}
if (!animating) {
break;
}
gifDecoder.advance();
try {
int delay = gifDecoder.getNextDelay();
// Sleep for frame duration minus time already spent on frame decode
// Actually we need next frame decode duration here,
// but I use previous frame time to make code more readable
delay -= frameDecodeTime;
if (delay > 0) {
Thread.sleep(framesDisplayDuration > 0 ? framesDisplayDuration : delay);
}
} catch (final Exception e) {
// suppress any exception
// it can be InterruptedException or IllegalArgumentException
}
}
} while (animating);
if (animationStopCallback != null) {
animationStopCallback.onAnimationStop();
}
}
public OnFrameAvailable getOnFrameAvailable() {
return frameCallback;
}
public void setOnFrameAvailable(OnFrameAvailable frameProcessor) {
this.frameCallback = frameProcessor;
}
public interface OnFrameAvailable {
Bitmap onFrameAvailable(Bitmap bitmap);
}
public OnAnimationStop getOnAnimationStop() {
return animationStopCallback;
}
public void setOnAnimationStop(OnAnimationStop animationStop) {
this.animationStopCallback = animationStop;
}
public interface OnAnimationStop {
void onAnimationStop();
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
clear();
}
}
回答1:
I had to play and pause the Gif image Glide - Cannot stop gif onClick- Getting TransitionDrawable instead of Animate/GifDrawable
The idea is to get drawable from view,checking if it is an instance of Gifdrawable and playing and pausing it.(Hoping the gif image is already playing)
Add this In OnClick of GifImageView
Drawable drawable = ((ImageView) v).getDrawable();
if (drawable instanceof GifDrawable) {
GifDrawable animatable = (GifDrawable) drawable;
if (animatable.isRunning()) {
animatable.stop();
} else {
animatable.start();
}
}
回答2:
I found the solution of above problem using GifMovieView!!!
GifMovieViewer.java
public class GifMovieViewer extends Activity {
private Button btnStart;
private GifMovieView gif1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gif_movie_viewer);
gif1 = (GifMovieView) findViewById(R.id.gif1);
btnStart = (Button) findViewById(R.id.btnStart);
btnStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
gif1.setMovieResource(R.drawable.earth_tilt_animation);
//for pause
// gif1.setPaused(gif1.isPaused());
}
});
}
public void onGifClick(View v) {
GifMovieView gif = (GifMovieView) v;
gif.setPaused(!gif.isPaused());
}
}
来源:https://stackoverflow.com/questions/37438197/set-gif-image-to-custom-imageview