Android Application series: Perfect running of the Image view in GIF format (with source code)
Foreword we all know that ImageView cannot perfectly load images in the Gif format. If the src resource in ImageView is in the gif format, we will be pleasantly surprised to find that the image remains in the first frame forever, that is, there will be no animation effect. Of course, after a slight transformation, we can make the gif perfectly loaded on the ImageView. Body Android provides a Movie class for us to load gif resources. We need to import the android. graphics. Movie package. Of course, this package is also provided by Android. Therefore, our main method is to inherit an ImageView subclass and load gif resources by rewriting the onDraw method. I will not talk much about it. You can better understand the code. The source code is included at the end of this article. PS: to understand this article, you need to know about custom views. Attrs resource file: <resources> <declare-styleable name = "GifView"> <attr name = "isgifimage" format = "boolean"/> </declare-styleable> </resources> I am here set a custom attribute isgifimage, the purpose is to allow users to set whether the control displays resources in gif format by themselves, because non-gif resources can be loaded with Movie to display images, but the efficiency is certainly not as good as the loading mode of native controls. Of course, the default isgifimage is true, that is, the default resource is in gif format. The custom GifView Constructor (the GifView class inherits ImageView) public GifView (Context context, AttributeSet attrs) {super (context, attrs ); // obtain the custom attribute isgifimage TypedArray array = context. obtainStyledAttributes (attrs, R. styleable. gifView); isGifImage = array. getBoolean (R. styleable. gifView_isgifimage, true); array. recycle (); // recycle is required after the custom attribute is obtained. Otherwise, it will affect the next retrieval. // obtain the default src attribute image = attrs of ImageView. getAttributeResourceValue ("ht Tp: // schemas.android.com/apk/res/android "," src ", 0); movie = Movie. decodeStream (getResources (). openRawResource (image);} in the GifView constructor, we mainly obtain the custom attributes of the GifView. You can use context. obtainStyledAttributes (attrs, R. styleable. gifView) returns a TypedArray object, and obtains the custom attributes from the object respectively. If you need to emphasize a little bit here, R. styleable. gifView_isgifimage: the name of the attrs resource file in red, while the blue value is the name of the corresponding attribute (see attrs resource file), separated by a line below. Recycle () is required after the custom attribute is obtained. Otherwise, it will affect the next time the control obtains the custom attribute, because the TypedArray object is a public resource. Then we get the native src attribute of the ImageView through attrs. getAttributeResourceValue ("http://schemas.android.com/apk/res/android", "src", 0) and pass it into the movie instance. The onDraw method @ Overrideprotected void onDraw (Canvas canvas) {super. onDraw (canvas); // execute the onDraw method of the parent class to draw non-gif resources if (isGifImage) {// if it is a gif file, execute DrawGifImage (), drawGifImage (canvas);} private void DrawGifImage (Canvas canvas) by default {// get the current system time long nowTime = android. OS. systemClock. currentThreadTimeMillis (); if (movieStart = 0) {// if it is the first load, set the start time to nowTime movieStart = nowTime;} if (movie! = Null) {// error tolerance Processing int duration = movie. duration (); // get the gif duration // if the gif duration is 100, you can consider it as a non-gif resource and exit the process if (duration = 0) {// obtain the time when the current gif frame is displayed. int relTime = (int) (nowTime-movieStart) % duration); movie. setTime (relTime); // render gif image movie. draw (canvas, 0, 0); invalidate () ;}} in this method, we first determine whether the isGifImage is true, if the developer specifies this parameter as false, super is called directly. the onDraw (canvas) can be drawn without calling DrawGifImage () to reduce efficiency. After all, the constant invalidate () is still very efficient in performance. If you want to draw a gif resource, we will deduce the time frame that the gif resource should display at the current time point based on the system time. I believe it is easier to understand the code, the annotations are also detailed enough, so we will not discuss them much. The xml file that calls the resource: <LinearLayout xmlns: android = "http://schemas.android.com/apk/res/android" xmlns: gifview = "http://schemas.android.com/apk/res/com.net168.testgifview" android: layout_width = "match_parent" android: layout_height = "match_parent"> <com.net168.gif view. gifView android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: src = "@ drawable/image" gifview: isgifimage = "false"/> </Line ArLayout> one thing to note is xmlns: gifview = "http://schemas.android.com/apk/res/com.net168.testgifview", where the red part of GifView. java is the package name of this class.