将GIF图像设置为自定义ImageView

时间:2016-05-25 13:08:37

标签: android animated-gif

我有动画GIF图像的自定义ImageView。我想显示GIF图像,我试过,但在这种情况下,它包含在Async中的URL而不是我想显示原始文件夹中的GIF图像而不使用Glide。任何人都知道如何显示图像?请guyz帮助解决这个问题!!!

我试过这个设置原始文件

 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();
  }
}

2 个答案:

答案 0 :(得分:0)

我必须播放并暂停Gif图像Glide - Cannot stop gif onClick- Getting TransitionDrawable instead of Animate/GifDrawable

我的想法是从视图中获取drawable,检查它是否是Gifdrawable的实例并播放和暂停它。(希望gif图像已经播放)

在Onif of GifImageView中添加此内容

Drawable drawable = ((ImageView) v).getDrawable();
if (drawable instanceof GifDrawable) {
         GifDrawable animatable = (GifDrawable) drawable;
         if (animatable.isRunning()) {
                 animatable.stop();
         } else {
                animatable.start();
         }
}

答案 1 :(得分:0)

我使用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());
    }
}