Display Animated GIF

后端 未结 30 1922
无人及你
无人及你 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:48

    Create a package named “Utils” under src folder and create a class named “GifImageView”

    public class GifImageView extends View {
        private InputStream mInputStream;
        private Movie mMovie;
        private int mWidth, mHeight;
        private long mStart;
        private Context mContext;
        public GifImageView(Context context) {
            super(context);
            this.mContext = context;
        }
        public GifImageView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
        public GifImageView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            this.mContext = context;
            if (attrs.getAttributeName(1).equals("background")) {
                int id = Integer.parseInt(attrs.getAttributeValue(1).substring(1));
                setGifImageResource(id);
            }
        }
        private void init() {
            setFocusable(true);
            mMovie = Movie.decodeStream(mInputStream);
            mWidth = mMovie.width();
            mHeight = mMovie.height();
            requestLayout();
        }
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            setMeasuredDimension(mWidth, mHeight);
        }
        @Override
        protected void onDraw(Canvas canvas) {
            long now = SystemClock.uptimeMillis();
            if (mStart == 0) {
                mStart = now;
            }
            if (mMovie != null) {
                int duration = mMovie.duration();
                if (duration == 0) {
                    duration = 1000;
                }
                int relTime = (int) ((now - mStart) % duration);
                mMovie.setTime(relTime);
                mMovie.draw(canvas, 0, 0);
                invalidate();
            }
        }
        public void setGifImageResource(int id) {
            mInputStream = mContext.getResources().openRawResource(id);
            init();
        }
        public void setGifImageUri(Uri uri) {
            try {
                mInputStream = mContext.getContentResolver().openInputStream(uri);
                init();
            } catch (FileNotFoundException e) {
                Log.e("GIfImageView", "File not found");
            }
        }
    }
    

    Now define GifImageView in MainActivity File: src/activity/MainActivity.class

    public class MainActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            GifImageView gifImageView = (GifImageView) findViewById(R.id.GifImageView);
            gifImageView.setGifImageResource(R.drawable.smartphone_drib);
        }
    }
    

    Now UI Part File: res/layout/activity_main.xml

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        android:gravity="center"
        android:background="#111E39"
        tools:context=".Activity.MainActivity">
        <com.android.animatedgif.Utils.GifImageView
            android:id="@+id/GifImageView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true" />
    
    </RelativeLayout>
    

    Resourece code : Android example

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

    Android actually can decode and display animated GIFs, using android.graphics.Movie class.

    This is not too much documented, but is in SDK Reference. Moreover, it is used in Samples in ApiDemos in BitmapDecode example with some animated flag.

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

    also put (main/assets/htmls/name.gif) [with this html adjust to the size]

    <html style="margin: 0;">
    <body style="margin: 0;">
    <img src="name.gif" style="width: 100%; height: 100%" />
    </body>
    </html>
    

    declare in your Xml for example like this (main/res/layout/name.xml): [you define the size, for example]

    <WebView
    android:layout_width="70dp"
    android:layout_height="70dp"
    android:id="@+id/webView"
    android:layout_gravity="center_horizontal" />
    

    in your Activity put the next code inside of onCreate

    web = (WebView) findViewById(R.id.webView); 
    web.setBackgroundColor(Color.TRANSPARENT); //for gif without background
    web.loadUrl("file:///android_asset/htmls/name.html");
    

    if you want load dynamically you have to load the webview with data:

    // or "[path]/name.gif" (e.g: file:///android_asset/name.gif for resources in asset folder), and in loadDataWithBaseURL(), you don't need to set base URL, on the other hand, it's similar to loadData() method.
    String gifName = "name.gif";
    String yourData = "<html style=\"margin: 0;\">\n" +
            "    <body style=\"margin: 0;\">\n" +
            "    <img src=" + gifName + " style=\"width: 100%; height: 100%\" />\n" +
            "    </body>\n" +
            "    </html>";
    // Important to add this attribute to webView to get resource from outside.
    webView.getSettings().setAllowFileAccess(true);
    
    // Notice: should use loadDataWithBaseURL. BaseUrl could be the base url such as the path to asset folder, or SDCard or any other path, where your images or the other media resides related to your html
    webView.loadDataWithBaseURL("file:///android_asset/", yourData, "text/html", "utf-8", null);
    // Or if you want to load image from SD card or where else, here is the idea.
    String base = Environment.getExternalStorageDirectory().getAbsolutePath().toString();
    webView.loadDataWithBaseURL(base + '/', yourData, "text/html", "utf-8", null);
    

    suggestion: is better load gif with static images for more information check https://developer.android.com/reference/android/graphics/drawable/AnimationDrawable.html

    That's it, I hope you help.

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

    Similar to what @Leonti said, but with a little more depth:

    What I did to solve the same problem was open up GIMP, hide all layers except for one, export it as its own image, and then hide that layer and unhide the next one, etc., until I had individual resource files for each one. Then I could use them as frames in the AnimationDrawable XML file.

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

    You may use GifAnimationDrawable library found in this link - https://github.com/Hipmob/gifanimateddrawable, and which convert any gif to AnimationDrawable. Enjoy :)

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

    UPDATE:

    Use glide:

    dependencies {
      implementation 'com.github.bumptech.glide:glide:4.0.0'
    }
    

    usage:

    Glide.with(context).load(GIF_URI).into(new GlideDrawableImageViewTarget(IMAGE_VIEW));
    

    see docs

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