[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-4127":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":16,"stars30d":17,"stars90d":16,"forks30d":16,"starsTrendScore":16,"compositeScore":18,"rankGlobal":10,"rankLanguage":10,"license":19,"archived":20,"fork":20,"defaultBranch":21,"hasWiki":22,"hasPages":22,"topics":23,"createdAt":10,"pushedAt":10,"updatedAt":29,"readmeContent":30,"aiSummary":31,"trendingCount":16,"starSnapshotCount":16,"syncStatus":32,"lastSyncTime":33,"discoverSource":34},4127,"android-gif-drawable","koral--\u002Fandroid-gif-drawable","koral--","Views and Drawable for displaying animated GIFs on Android","",null,"Java",9647,1786,306,32,0,9,40.76,"Other",false,"dev",true,[24,25,26,27,28],"android","animated-gifs","drawable","gif","hacktoberfest","2026-06-12 02:00:59","![horizontal.png](https:\u002F\u002Fcdn.steemitimages.com\u002FDQmacEdVnEf1f2GDZ4uga1evN3FzujdR4zbkqmiV7NscPBs\u002Fhorizontal.png)\n====================\n[![Maven Central](https:\u002F\u002Fmaven-badges.herokuapp.com\u002Fmaven-central\u002Fpl.droidsonroids.gif\u002Fandroid-gif-drawable\u002Fbadge.svg)](https:\u002F\u002Fmaven-badges.herokuapp.com\u002Fmaven-central\u002Fpl.droidsonroids.gif\u002Fandroid-gif-drawable)\n[![Build Status](https:\u002F\u002Fapp.bitrise.io\u002Fapp\u002F78fd40a5596e97e7\u002Fstatus.svg?token=SMUtlPklcIRBODd513ZdiQ)](https:\u002F\u002Fapp.bitrise.io\u002Fapp\u002F78fd40a5596e97e7)\n[![Android Arsenal](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FAndroid%20Arsenal-android--gif--drawable-brightgreen.svg?style=flat)](https:\u002F\u002Fandroid-arsenal.com\u002Fdetails\u002F1\u002F1147)\n[![Android-Libs](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FAndroid--Libs-android--gif--drawable-orange.svg?style=flat)](http:\u002F\u002Fandroid-libs.com\u002Flib\u002Fandroid-gif-drawable)\n[![Android Weekly](http:\u002F\u002Fimg.shields.io\u002Fbadge\u002FAndroid%20Weekly-%2393-2CB3E5.svg?style=flat)](http:\u002F\u002Fandroidweekly.net\u002Fissues\u002Fissue-93)\n[![API](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FAPI-17%2B-blue.svg?style=flat)](https:\u002F\u002Fandroid-arsenal.com\u002Fapi?level=17)\n[![Javadocs](http:\u002F\u002Fwww.javadoc.io\u002Fbadge\u002Fpl.droidsonroids.gif\u002Fandroid-gif-drawable.svg)](http:\u002F\u002Fwww.javadoc.io\u002Fdoc\u002Fpl.droidsonroids.gif\u002Fandroid-gif-drawable)\n[![OpenSSF Scorecard](https:\u002F\u002Fapi.securityscorecards.dev\u002Fprojects\u002Fgithub.com\u002Fkoral--\u002Fandroid-gif-drawable\u002Fbadge)](https:\u002F\u002Fapi.securityscorecards.dev\u002Fprojects\u002Fgithub.com\u002Fkoral--\u002Fandroid-gif-drawable)\n\n`View`s and `Drawable` for animated GIFs in Android.\n\n## Overview\nBundled GIFLib via JNI is used to render frames. This way should be more efficient than `WebView` or `Movie` classes.\n\n### [Javadoc](http:\u002F\u002Fwww.javadoc.io\u002Fdoc\u002Fpl.droidsonroids.gif\u002Fandroid-gif-drawable)\n\n### Setup\n\n#### Gradle (Android Studio)\nInsert the following dependency to `build.gradle` file of your project.\n```groovy\ndependencies {\n    implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.31'\n}\n```\nNote that Maven central repository should be defined eg. in top-level `build.gradle` like this:\n```groovy \nbuildscript {\n    repositories {\n        mavenCentral()\n    }\n}\nallprojects {\n    repositories {\n        mavenCentral()\n    }\n}\n```\n#### Gradle, snapshot repository\nCurrent development builds (build from `dev` branch) are published to OSS snapshot repository. To use them, specify repository URL in `repositories` block:\n```groovy\nrepositories {\n    mavenCentral()\n    maven { url \"https:\u002F\u002Foss.sonatype.org\u002Fcontent\u002Frepositories\u002Fsnapshots\" }\n}\ndependencies {\n    implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.+'\n}\n```\n#### Maven dependency\n\n```xml\n\u003Cdependency>\n    \u003CgroupId>pl.droidsonroids.gif\u003C\u002FgroupId>\n    \u003CartifactId>android-gif-drawable\u003C\u002FartifactId>\n    \u003Cversion>insert latest version here\u003C\u002Fversion>\n    \u003Ctype>aar\u003C\u002Ftype>\n\u003C\u002Fdependency>\n```\n#### Eclipse\nSee [Sample eclipse project](https:\u002F\u002Fgithub.com\u002Fkoral--\u002Fandroid-gif-drawable-eclipse-sample) with setup instructions.\n\n#### Download\n\n**[Latest release downloads](https:\u002F\u002Fgithub.com\u002Fkoral--\u002Fandroid-gif-drawable\u002Freleases\u002Flatest)**\n\n### Requirements\n+ Android 4.2+ (API level 17+)\n+ for `GifTextureView` hardware-accelerated rendering\n+ for `GifTexImage2D` OpenGL ES 2.0+\n\n#### Building from source\n+ [Android NDK](http:\u002F\u002Fdeveloper.android.com\u002Ftools\u002Fsdk\u002Fndk\u002Findex.html) needed to compile native sources\n\n## Usage\n\n### Sample project\nSee `sample` directory. Sample project is under construction. Not all features are covered yet.\n\n### From XML\nThe simplest way is to use `GifImageView` (or `GifImageButton`) like a normal `ImageView`:\n```xml\n\u003Cpl.droidsonroids.gif.GifImageView\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:src=\"@drawable\u002Fsrc_anim\"\n    android:background=\"@drawable\u002Fbg_anim\"\n    \u002F>\n```\n\nIf drawables declared by `android:src` and\u002For `android:background` are GIF files then they \nwill be automatically recognized as `GifDrawable`s and animated. If given drawable is not a GIF then\nmentioned Views work like plain `ImageView` and `ImageButton`.\n\n`GifTextView` allows you to use GIFs as compound drawables and background.\n```xml\n\u003Cpl.droidsonroids.gif.GifTextView\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:drawableTop=\"@drawable\u002Fleft_anim\"\n    android:drawableStart=\"@drawable\u002Fleft_anim\"\n    android:background=\"@drawable\u002Fbg_anim\"\n    \u002F>\n```\n\n### From Java code\n`GifImageView`, `GifImageButton` and `GifTextView` have also hooks for setters implemented. So animated GIFs can be set by calling `setImageResource(int resId)` and `setBackgroundResource(int resId)`\n\n`GifDrawable` can be constructed directly from various sources:\n\n```java\n\u002F\u002Fasset file\nGifDrawable gifFromAssets = new GifDrawable( getAssets(), \"anim.gif\" );\n\t\t\n\u002F\u002Fresource (drawable or raw)\nGifDrawable gifFromResource = new GifDrawable( getResources(), R.drawable.anim );\n\t\t\n\u002F\u002FUri\nContentResolver contentResolver = ... \u002F\u002Fcan be null for file:\u002F\u002F Uris\nGifDrawable gifFromUri = new GifDrawable( contentResolver, gifUri );\n\n\u002F\u002Fbyte array\nbyte[] rawGifBytes = ...\nGifDrawable gifFromBytes = new GifDrawable( rawGifBytes );\n\t\t\n\u002F\u002FFileDescriptor\nFileDescriptor fd = new RandomAccessFile( \"\u002Fpath\u002Fanim.gif\", \"r\" ).getFD();\nGifDrawable gifFromFd = new GifDrawable( fd );\n\t\t\n\u002F\u002Ffile path\nGifDrawable gifFromPath = new GifDrawable( \"\u002Fpath\u002Fanim.gif\" );\n\t\t\n\u002F\u002Ffile\nFile gifFile = new File(getFilesDir(),\"anim.gif\");\nGifDrawable gifFromFile = new GifDrawable(gifFile);\n\t\t\n\u002F\u002FAssetFileDescriptor\nAssetFileDescriptor afd = getAssets().openFd( \"anim.gif\" );\nGifDrawable gifFromAfd = new GifDrawable( afd );\n\t\t\t\t\n\u002F\u002FInputStream (it must support marking)\nInputStream sourceIs = ...\nBufferedInputStream bis = new BufferedInputStream( sourceIs, GIF_LENGTH );\nGifDrawable gifFromStream = new GifDrawable( bis );\n\t\t\n\u002F\u002Fdirect ByteBuffer\nByteBuffer rawGifBytes = ...\nGifDrawable gifFromBytes = new GifDrawable( rawGifBytes );\t\n````\nInputStreams are closed automatically in finalizer if GifDrawable is no longer needed \nso you don't need to explicitly close them. Calling `recycle()` will also close \nunderlying input source. \n\nNote that all input sources need to have ability to rewind to the beginning. It is required to correctly play animated GIFs \n(where animation is repeatable) since subsequent frames are decoded on demand from source.\n\n#### Animation control\n`GifDrawable` implements an `Animatable` and `MediaPlayerControl` so you can use its methods and more:\n\n+ `stop()` - stops the animation, can be called from any thread\n+ `start()` - starts the animation, can be called from any thread\n+ `isRunning()` - returns whether animation is currently running or not\n+ `reset()` - rewinds the animation, does not restart stopped one\n+ `setSpeed(float factor)` - sets new animation speed factor, eg. passing 2.0f will double the animation speed\n+ `seekTo(int position)` - seeks animation (within current loop) to given `position` (in milliseconds)\n+ `getDuration()` - returns duration of one loop of the animation\n+ `getCurrentPosition()` - returns elapsed time from the beginning of a current loop of animation\n\n##### Using [MediaPlayerControl](http:\u002F\u002Fdeveloper.android.com\u002Freference\u002Fandroid\u002Fwidget\u002FMediaController.MediaPlayerControl.html)\nStandard controls for a MediaPlayer (like in [VideoView](http:\u002F\u002Fdeveloper.android.com\u002Freference\u002Fandroid\u002Fwidget\u002FVideoView.html)) can be used to control GIF animation and show its current progress.\n\nJust set `GifDrawable` as MediaPlayer on your [MediaController](http:\u002F\u002Fdeveloper.android.com\u002Freference\u002Fandroid\u002Fwidget\u002FMediaController.html) like this:\n```java\n@Override\nprotected void onCreate(Bundle savedInstanceState) {\n    super.onCreate(savedInstanceState);\n    GifImageButton gib = new GifImageButton(this);\n    setContentView(gib);\n    gib.setImageResource(R.drawable.sample);\n    final MediaController mc = new MediaController(this);\n    mc.setMediaPlayer((GifDrawable) gib.getDrawable());\n    mc.setAnchorView(gib);\n    gib.setOnClickListener(new OnClickListener() {\n        @Override\n        public void onClick(View v) {\n            mc.show();\n        }\n   });\n}\n```\n\n#### Retrieving GIF metadata\n\n+ `getLoopCount()` - returns a loop count as defined in `NETSCAPE 2.0` extension\n+ `getNumberOfFrames()` - returns number of frames (at least 1)\n+ `getComment()` - returns comment text (`null` if GIF has no comment)\n+ `getFrameByteCount()` - returns minimum number of bytes that can be used to store pixels of the single frame\n+ `getAllocationByteCount()` - returns size (in bytes) of the allocated memory used to store pixels of given GifDrawable\n+ `getInputSourceByteCount()` - returns length (in bytes) of the backing input data\n+ `toString()` - returns human readable information about image size and number of frames (intended for debugging purpose)\n\n#### Associating single `GifDrawable` instance with multiple `View`s\n\nNormally single `GifDrawable` instance associated with multiple `View`s will animate only on the last one.\nTo solve that create `MultiCallback` instance, add `View`s to it and set callback for given drawable, e.g.:\n```java\nMultiCallback multiCallback = new MultiCallback();\n\nimageView.setImageDrawable(gifDrawable);\nmultiCallback.addView(imageView);\n\nanotherImageView.setImageDrawable(gifDrawable);\nmultiCallback.addView(anotherImageView);\n\ngifDrawable.setCallback(multiCallback);\n```\n\nNote that if you change a drawable of e.g. `ImageView`, the callback will be removed from the previous\ndrawable. Thereafter, you have to reassign callback or the same `GifDrawable` instance will stop animating. \nSee [#480](https:\u002F\u002Fgithub.com\u002Fkoral--\u002Fandroid-gif-drawable\u002Fissues\u002F480) for more information.\n\n#### Advanced\n \n+ `recycle()` - provided to speed up freeing memory (like in `android.graphics.Bitmap`)\n+ `isRecycled()` - checks whether drawable is recycled\n+ `getError()` - returns last error details\n\n## Upgrading from 1.2.15\n#### Minimum SDK version changed\nMinimum API level is now 17 (Android 4.2).\n`armeabi` (arm v5 and v6) is no longer supported. \n\n## Upgrading from 1.2.8\n#### Minimum SDK version changed\nMinimum API level is now 14 (Android 4.0).\n\n## Upgrading from 1.2.3\nMeaningful only if consumer proguard rules (bundled with library) are **not** used (they are used by default by Gradle).\n+ Proguard rule has changed to `-keep public class pl.droidsonroids.gif.GifIOException{\u003Cinit>(int, java.lang.String);}` \n\n## Upgrading from 1.1.17\n1.1.17 is the last version supporting API level 8 (Froyo). Starting from 1.2.0 minimum API level is 9 (Gingerbread).\n\n## Upgrading from 1.1.13\nHandling of several edge cases has been changed:\n+ `GifDrawable#getNumberOfFrames()` now returns 0 when `GifDrawable` is recycled\n+ Information included in result of `GifDrawable#toString()` when `GifDrawable` is recycled now contains zeroes only\n\n## Upgrading from 1.1.10\nIt is recommended (but not required) to call `LibraryLoader.initialize()` before using `GifDrawable`. `Context` is needed in some cases\nwhen native libraries cannot be extracted normally. See [ReLinker](https:\u002F\u002Fmedium.com\u002Fkeepsafe-engineering\u002Fthe-perils-of-loading-native-libraries-on-android-befa49dce2db)\nfor more details. \nIf `LibraryLoader.initialize()` was not called and normal library loading fails, `Context` will be tried to be retrieved in fall back way which may not always work.   \n\n## Upgrading from 1.1.9\n`int` parameter `loopNumber` has been added to `AnimationListener#onAnimationCompleted()`.\n\n## Upgrading from 1.1.8\n#### Proguard configuration not needed\nProguard configuration is now bundled with the library, you don't need to specify it yourself.\n\n## Upgrading from 1.1.3\n`src` XML attribute in `GifTextureView` has been renamed to `gifSource` to avoid possible conflicts with other libraries.\n\n## Upgrading from 1.0.x\n#### Proguard configuration update\nProguard configuration has changed to:\n```\n-keep public class pl.droidsonroids.gif.GifIOException{\u003Cinit>(int);}\n-keep class pl.droidsonroids.gif.GifInfoHandle{\u003Cinit>(long,int,int,int);}\n```\n\n#### Drawable recycling behavior change\n`GifDrawable` now uses `android.graphics.Bitmap` as frame buffer. Trying to access pixels (including drawing)\n of recycled `GifDrawable` will cause `IllegalStateException` like in `Bitmap`.\n\n#### Minimum SDK version changed\nMinimum API level is now 8 (Android 2.2).\n\n#### Rendering moved to background thread\nRendering is performed in background thread running independently from main thread so animation is running\neven if drawable is not drawn. However rendering is not running if drawable is not visible, see [#setVisible()](http:\u002F\u002Fdeveloper.android.com\u002Freference\u002Fandroid\u002Fgraphics\u002Fdrawable\u002FDrawable.html#setVisible(boolean, boolean)).\nThat method can be used to control drawable visibility in cases when it is not already handled by Android framework.\n\n## References\nThis library uses code from [GIFLib](http:\u002F\u002Fgiflib.sourceforge.net\u002F) 5.1.3 and [SKIA](https:\u002F\u002Fcode.google.com\u002Fp\u002Fskia\u002F).\n\n### Projects using android-gif-drawable\n[ImageFactory](https:\u002F\u002Fgithub.com\u002FDoctoror\u002FImageFactory)\n\n[NativeScript Plugin by Brad Martin](https:\u002F\u002Fgithub.com\u002Fbradmartin\u002Fnativescript-gif) available on [NPM](https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Fnativescript-gif)\n\n[Sketch](https:\u002F\u002Fgithub.com\u002Fxiaopansky\u002FSketch) Powerful and comprehensive image loader on Android, with support for GIF, gesture zooming, block display super large image.\n\nWant to include your project here? [Fill an issue](https:\u002F\u002Fgithub.com\u002Fkoral--\u002Fandroid-gif-drawable\u002Fissues\u002Fnew)\n\n## License\n\nMIT License\u003Cbr>\nSee [LICENSE](LICENSE) file.\n","该项目提供了一套用于在Android平台上显示动画GIF的View和Drawable组件。它通过JNI绑定GIFLib来渲染帧，相比使用WebView或Movie类的方法更加高效。支持API 17及以上版本，并提供了详细的Javadoc文档。适用于需要在应用中展示GIF动画的各种场景，如游戏加载界面、聊天表情包等。集成方式简单，支持Gradle、Maven等多种构建工具，便于开发者快速上手。",2,"2026-06-11 02:58:35","top_language"]