【问题标题】:Set GIF image to Custom ImageView将 GIF 图片设置为自定义 ImageView
【发布时间】:2016-05-25 13:08:36
【问题描述】:

我有用于动画 GIF 图像的自定义 ImageView。我想显示 GIF 图像,我尝试过,但在这种情况下它包含异步中的 url,而不是我想在不使用 Glide 的情况下显示原始文件夹中的 GIF 图像。有人知道如何显示图像吗?请大佬帮忙解决这个问题!!!

我试过这个设置原始文件

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

【问题讨论】:

  • Glide 也提供了 GIF 动画支持,那何乐而不为呢。
  • 我知道,但我想在点击视图时开始和停止动画,所以我不能使用 Glide
  • 关于开始和停止 gif 图像的任何想法都需要滑动
  • 是的..我看过这个,但这里的评论是,它不是 gif。它是用于png的,所以我没有尝试

标签: android animated-gif


【解决方案1】:

我不得不播放和暂停 Gif 图片Glide - Cannot stop gif onClick- Getting TransitionDrawable instead of Animate/GifDrawable

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

在 GifImageView 的 OnClick 中添加这个

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

【讨论】:

  • 对不起,我无法展示它,你知道我更新的代码吗?
  • 你更新的代码在哪里?我看不到任何..你确定你在使用 Glide 吗?
  • 我的意思是你知道我上面的代码没有使用 Glide 吗?
  • 不,我还没有使用 GifDecoder,所以帮不上忙。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-24
    • 2019-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多