Display Animated GIF

后端 未结 30 1923
无人及你
无人及你 2020-11-22 02:11

I want to display animated GIF images in my aplication. As I found out the hard way Android doesn\'t support animated GIF natively.

However it can display animations

相关标签:
30条回答
  • 2020-11-22 02:33

    The easy way to display animated GIF directly from URL to your app layout is to use WebView class.

    Step 1: In your layout XML

    <WebView
    android:id="@+id/webView"
    android:layout_width="50dp"
    android:layout_height="50dp"
    />

    Step 2: In your Activity

    WebView wb;
    wb = (WebView) findViewById(R.id.webView);
    wb.loadUrl("https://.......);

    Step 3: In your Manifest.XML make Internet permission

    <uses-permission android:name="android.permission.INTERNET" />

    Step 4: In case you want to make your GIF background transparent and make GIF fit to your Layout

    wb.setBackgroundColor(Color.TRANSPARENT);
    wb.getSettings().setLoadWithOverviewMode(true);
    wb.getSettings().setUseWideViewPort(true);

    0 讨论(0)
  • 2020-11-22 02:34
    public class Test extends GraphicsActivity {
    
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new SampleView(this));
      }
    
      private static class SampleView extends View {
        private Bitmap mBitmap;
        private Bitmap mBitmap2;
        private Bitmap mBitmap3;
        private Bitmap mBitmap4;
        private Drawable mDrawable;
    
        private Movie mMovie;
        private long mMovieStart;
    
        // Set to false to use decodeByteArray
        private static final boolean DECODE_STREAM = true;
    
        private static byte[] streamToBytes(InputStream is) {
          ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
          byte[] buffer = new byte[1024];
          int len;
          try {
            while ((len = is.read(buffer)) >= 0) {
              os.write(buffer, 0, len);
            }
          } catch (java.io.IOException e) {
          }
          return os.toByteArray();
        }
    
        public SampleView(Context context) {
          super(context);
          setFocusable(true);
    
          java.io.InputStream is;
          is = context.getResources().openRawResource(R.drawable.icon);
    
          BitmapFactory.Options opts = new BitmapFactory.Options();
          Bitmap bm;
    
          opts.inJustDecodeBounds = true;
          bm = BitmapFactory.decodeStream(is, null, opts);
    
          // now opts.outWidth and opts.outHeight are the dimension of the
          // bitmap, even though bm is null
    
          opts.inJustDecodeBounds = false; // this will request the bm
          opts.inSampleSize = 4; // scaled down by 4
          bm = BitmapFactory.decodeStream(is, null, opts);
    
          mBitmap = bm;
    
          // decode an image with transparency
          is = context.getResources().openRawResource(R.drawable.icon);
          mBitmap2 = BitmapFactory.decodeStream(is);
    
          // create a deep copy of it using getPixels() into different configs
          int w = mBitmap2.getWidth();
          int h = mBitmap2.getHeight();
          int[] pixels = new int[w * h];
          mBitmap2.getPixels(pixels, 0, w, 0, 0, w, h);
          mBitmap3 = Bitmap.createBitmap(pixels, 0, w, w, h,
              Bitmap.Config.ARGB_8888);
          mBitmap4 = Bitmap.createBitmap(pixels, 0, w, w, h,
              Bitmap.Config.ARGB_4444);
    
          mDrawable = context.getResources().getDrawable(R.drawable.icon);
          mDrawable.setBounds(150, 20, 300, 100);
    
          is = context.getResources().openRawResource(R.drawable.animated_gif);
    
          if (DECODE_STREAM) {
            mMovie = Movie.decodeStream(is);
          } else {
            byte[] array = streamToBytes(is);
            mMovie = Movie.decodeByteArray(array, 0, array.length);
          }
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
          canvas.drawColor(0xFFCCCCCC);
    
          Paint p = new Paint();
          p.setAntiAlias(true);
    
          canvas.drawBitmap(mBitmap, 10, 10, null);
          canvas.drawBitmap(mBitmap2, 10, 170, null);
          canvas.drawBitmap(mBitmap3, 110, 170, null);
          canvas.drawBitmap(mBitmap4, 210, 170, null);
    
          mDrawable.draw(canvas);
    
          long now = android.os.SystemClock.uptimeMillis();
          if (mMovieStart == 0) { // first time
            mMovieStart = now;
          }
          if (mMovie != null) {
            int dur = mMovie.duration();
            if (dur == 0) {
              dur = 1000;
            }
            int relTime = (int) ((now - mMovieStart) % dur);
            mMovie.setTime(relTime);
            mMovie.draw(canvas, getWidth() - mMovie.width(), getHeight()
                - mMovie.height());
            invalidate();
          }
        }
      }
    }
    
    class GraphicsActivity extends Activity {
      // set to true to test Picture
      private static final boolean TEST_PICTURE = false;
    
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
      }
    
      @Override
      public void setContentView(View view) {
        if (TEST_PICTURE) {
          ViewGroup vg = new PictureLayout(this);
          vg.addView(view);
          view = vg;
        }
    
        super.setContentView(view);
      }
    }
    
    class PictureLayout extends ViewGroup {
      private final Picture mPicture = new Picture();
    
      public PictureLayout(Context context) {
        super(context);
      }
    
      public PictureLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
      }
    
      @Override
      public void addView(View child) {
        if (getChildCount() > 1) {
          throw new IllegalStateException(
              "PictureLayout can host only one direct child");
        }
    
        super.addView(child);
      }
    
      @Override
      public void addView(View child, int index) {
        if (getChildCount() > 1) {
          throw new IllegalStateException(
              "PictureLayout can host only one direct child");
        }
    
        super.addView(child, index);
      }
    
      @Override
      public void addView(View child, LayoutParams params) {
        if (getChildCount() > 1) {
          throw new IllegalStateException(
              "PictureLayout can host only one direct child");
        }
    
        super.addView(child, params);
      }
    
      @Override
      public void addView(View child, int index, LayoutParams params) {
        if (getChildCount() > 1) {
          throw new IllegalStateException(
              "PictureLayout can host only one direct child");
        }
    
        super.addView(child, index, params);
      }
    
      @Override
      protected LayoutParams generateDefaultLayoutParams() {
        return new LayoutParams(LayoutParams.MATCH_PARENT,
            LayoutParams.MATCH_PARENT);
      }
    
      @Override
      protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        final int count = getChildCount();
    
        int maxHeight = 0;
        int maxWidth = 0;
    
        for (int i = 0; i < count; i++) {
          final View child = getChildAt(i);
          if (child.getVisibility() != GONE) {
            measureChild(child, widthMeasureSpec, heightMeasureSpec);
          }
        }
    
        maxWidth += getPaddingLeft() + getPaddingRight();
        maxHeight += getPaddingTop() + getPaddingBottom();
    
        Drawable drawable = getBackground();
        if (drawable != null) {
          maxHeight = Math.max(maxHeight, drawable.getMinimumHeight());
          maxWidth = Math.max(maxWidth, drawable.getMinimumWidth());
        }
    
        setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec),
            resolveSize(maxHeight, heightMeasureSpec));
      }
    
      private void drawPict(Canvas canvas, int x, int y, int w, int h, float sx,
          float sy) {
        canvas.save();
        canvas.translate(x, y);
        canvas.clipRect(0, 0, w, h);
        canvas.scale(0.5f, 0.5f);
        canvas.scale(sx, sy, w, h);
        canvas.drawPicture(mPicture);
        canvas.restore();
      }
    
      @Override
      protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight()));
        mPicture.endRecording();
    
        int x = getWidth() / 2;
        int y = getHeight() / 2;
    
        if (false) {
          canvas.drawPicture(mPicture);
        } else {
          drawPict(canvas, 0, 0, x, y, 1, 1);
          drawPict(canvas, x, 0, x, y, -1, 1);
          drawPict(canvas, 0, y, x, y, 1, -1);
          drawPict(canvas, x, y, x, y, -1, -1);
        }
      }
    
      @Override
      public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
        location[0] = getLeft();
        location[1] = getTop();
        dirty.set(0, 0, getWidth(), getHeight());
        return getParent();
      }
    
      @Override
      protected void onLayout(boolean changed, int l, int t, int r, int b) {
        final int count = super.getChildCount();
    
        for (int i = 0; i < count; i++) {
          final View child = getChildAt(i);
          if (child.getVisibility() != GONE) {
            final int childLeft = getPaddingLeft();
            final int childTop = getPaddingTop();
            child.layout(childLeft, childTop,
                childLeft + child.getMeasuredWidth(),
                childTop + child.getMeasuredHeight());
    
          }
        }
      }
    }
    
    0 讨论(0)
  • 2020-11-22 02:36

    Put it into a WebView, it has to be able to display it correctly, since the default browser supports gif files. (Froyo+, if i am not mistaken)

    0 讨论(0)
  • 2020-11-22 02:37

    I solved this by spliting gif in frames and use standard android animation

    0 讨论(0)
  • 2020-11-22 02:38

    I had a really hard time to have animated gif working in Android. I only had following two working:

    1. WebView
    2. Ion

    WebView works OK and really easy, but the problem is it makes the view loads slower and the app would be unresponsive for a second or so. I did not like that. So I have tried different approaches (DID NOT WORK):

    1. ImageViewEx is deprecated!
    2. picasso did not load animated gif
    3. android-gif-drawable looks great, but it caused some wired NDK issues in my project. It caused my local NDK library stop working, and I was not able to fix it

    I had some back and forth with Ion; Finally, I have it working, and it is really fast :-)

    Ion.with(imgView)
      .error(R.drawable.default_image)
      .animateGif(AnimateGifMode.ANIMATE)
      .load("file:///android_asset/animated.gif");
    
    0 讨论(0)
  • 2020-11-22 02:38

    I think the better library to handle gif files is this one: by koral

    Used it and i'm successful and this library is dedicated to GIF'S; but where as the picasso and glide are general purpose image framework; so i think the developers of this library have entirely concentrated on gif files

    0 讨论(0)
提交回复
热议问题