[Android开发]Gif图片下载和显示
来源:互联网 发布:nginx阿里云绑定域名 编辑:程序博客网 时间:2024/06/05 10:43
浏览了很多网上很多关于Gif图片显示的资料,总结起来一共为四种方案:
1.使用GitHub:android-gif-drawable ,具体方法网上很多参考。
缺点:目前GitHub上的源码是使用AndroidStudio写的,使用Eclipse编译起来比较麻烦,而且,使用jni,对于一般跟我一样水平的一时还搞不明白,且使用下载的最近的jar包某些机型会报jni的错,比如HTC M8 和三星S4.
2.使用GifView,该种方案在网上使用较多,参考资料也较多,说一说我使用该jar包遇到的问题,在加载大量图片的时候,我加载了一共9张图,显示第3张的时候出现OOM。
3.使用Movie,这是我在使用以上两种方案不成功之后,采用的方案,一会具体说说实现过程。
4.使用webview,该种方法没有写demo测试,具体可行性为止,看到有人问,如何释放webview加载的资源,应该是存在这样的问题的,但是,如果可以解决,也不失为一种好的方案。
具体说一说,第三种方案,使用Movie现实现实Gif图片。
/** * This is a View class that wraps Android {@link Movie} object and displays it. * You can set GIF as a Movie object or as a resource id from XML or by calling * {@link #setMovie(Movie)} or {@link #setMovieResource(int)}. * <p> * You can pause and resume GIF animation by calling {@link #setPaused(boolean)}. * <p> * The animation is drawn in the center inside of the measured view bounds. * * @author Sergey Bakhtiarov */public class GifMovieView extends View {private static final int DEFAULT_MOVIEW_DURATION = 1000;private int mMovieResourceId;private Movie mMovie;private long mMovieStart;private int mCurrentAnimationTime = 0;/** * Position for drawing animation frames in the center of the view. */private float mLeft;private float mTop;/** * Scaling factor to fit the animation within view bounds. */private float mScale;//控制图片显示大小/** * Scaled movie frames width and height. */private int mMeasuredMovieWidth;private int mMeasuredMovieHeight;private volatile boolean mPaused = false;private boolean mVisible = true;public GifMovieView(Context context) {this(context, null);}public GifMovieView(Context context, AttributeSet attrs) {this(context, attrs, R.styleable.CustomTheme_gifMoviewViewStyle);}public GifMovieView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);setViewAttributes(context, attrs, defStyle);}@SuppressLint("NewApi")private void setViewAttributes(Context context, AttributeSet attrs,int defStyle) {/** * Starting from HONEYCOMB have to turn off HW acceleration to draw * Movie on Canvas. */if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {setLayerType(View.LAYER_TYPE_SOFTWARE, null);}final TypedArray array = context.obtainStyledAttributes(attrs,R.styleable.GifMoviewView, defStyle,R.style.Widget_GifMoviewView);mMovieResourceId = array.getResourceId(R.styleable.GifMoviewView_gif,-1);mPaused = array.getBoolean(R.styleable.GifMoviewView_paused, false);array.recycle();if (mMovieResourceId != -1) {mMovie = Movie.decodeStream(getResources().openRawResource(mMovieResourceId));}}public void setMovieInputStream(InputStream is) {if (is.markSupported()) {try {int readlimit = is.available();is.mark(readlimit);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}mMovie = Movie.decodeStream(is);requestLayout();}public void setMovieResource(int movieResId) {this.mMovieResourceId = movieResId;mMovie = Movie.decodeStream(getResources().openRawResource(mMovieResourceId));requestLayout();}public void setMovie(Movie movie) {this.mMovie = movie;requestLayout();}public Movie getMovie() {return mMovie;}public void setMovieTime(int time) {mCurrentAnimationTime = time;invalidate();}public void setPaused(boolean paused) {this.mPaused = paused;/** * Calculate new movie start time, so that it resumes from the same * frame. */if (!paused) {mMovieStart = android.os.SystemClock.uptimeMillis()- mCurrentAnimationTime;}invalidate();}public boolean isPaused() {return this.mPaused;}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {if (mMovie != null) {int movieWidth = mMovie.width();int movieHeight = mMovie.height();/* * Calculate horizontal scaling */float scaleH = 1f;int measureModeWidth = MeasureSpec.getMode(widthMeasureSpec);if (measureModeWidth != MeasureSpec.UNSPECIFIED) {int maximumWidth = MeasureSpec.getSize(widthMeasureSpec);if (maximumWidth > movieWidth) {scaleH = (float) maximumWidth / (float) movieWidth;}}/* * calculate vertical scaling */float scaleW = 1f;int measureModeHeight = MeasureSpec.getMode(heightMeasureSpec);if (measureModeHeight != MeasureSpec.UNSPECIFIED) {int maximumHeight = MeasureSpec.getSize(heightMeasureSpec);if (maximumHeight > movieHeight) {scaleW = (float) maximumHeight / (float) movieHeight;}}/* * calculate overall scale */mScale = Math.min(scaleH, scaleW);mMeasuredMovieWidth = (int) (movieWidth * mScale);mMeasuredMovieHeight = (int) (movieHeight * mScale);setMeasuredDimension(mMeasuredMovieWidth, mMeasuredMovieHeight);} else {/* * No movie set, just set minimum available size. */setMeasuredDimension(getSuggestedMinimumWidth(),getSuggestedMinimumHeight());}}@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {super.onLayout(changed, l, t, r, b);/* * Calculate left / top for drawing in center */mLeft = (getWidth() - mMeasuredMovieWidth) / 2f;mTop = (getHeight() - mMeasuredMovieHeight) / 2f;mVisible = getVisibility() == View.VISIBLE;}@Overrideprotected void onDraw(Canvas canvas) {if (mMovie != null) {if (!mPaused) {updateAnimationTime();drawMovieFrame(canvas);invalidateView();} else {drawMovieFrame(canvas);}}}/** * Invalidates view only if it is visible. <br> * {@link #postInvalidateOnAnimation()} is used for Jelly Bean and higher. * */@SuppressLint("NewApi")private void invalidateView() {if (mVisible) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {postInvalidateOnAnimation();} else {invalidate();}}}/** * Calculate current animation time */private void updateAnimationTime() {long now = android.os.SystemClock.uptimeMillis();if (mMovieStart == 0) {mMovieStart = now;}int dur = mMovie.duration();if (dur == 0) {dur = DEFAULT_MOVIEW_DURATION;}mCurrentAnimationTime = (int) ((now - mMovieStart) % dur);}/** * Draw current GIF frame */private void drawMovieFrame(Canvas canvas) {mMovie.setTime(mCurrentAnimationTime);canvas.save(Canvas.MATRIX_SAVE_FLAG);canvas.scale(mScale, mScale);mMovie.draw(canvas, mLeft / mScale, mTop / mScale);canvas.restore();}@SuppressLint("NewApi")@Overridepublic void onScreenStateChanged(int screenState) {super.onScreenStateChanged(screenState);mVisible = screenState == SCREEN_STATE_ON;invalidateView();}@SuppressLint("NewApi")@Overrideprotected void onVisibilityChanged(View changedView, int visibility) {super.onVisibilityChanged(changedView, visibility);mVisible = visibility == View.VISIBLE;invalidateView();}@Overrideprotected void onWindowVisibilityChanged(int visibility) {super.onWindowVisibilityChanged(visibility);mVisible = visibility == View.VISIBLE;invalidateView();}}
<resources> <declare-styleable name="GifMoviewView"> <attr name="gif" format="reference" /> <attr name="paused" format="boolean" /> </declare-styleable> <declare-styleable name="CustomTheme"> <attr name="gifMoviewViewStyle" format="reference" /> </declare-styleable></resources>
<com.example.ui.view.GifMovieView android:id="@+id/gif_image" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center" />
File gifFile = new File(result);BufferedInputStream bis = new BufferedInputStream(new FileInputStream(gifFile));<pre name="code" class="html"><span style="white-space: pre;"></span>iv_header.setMovieInputStream(bis);
Finish。
0 0
- [Android开发]Gif图片下载和显示
- android 图片下载并显示
- Android 图片下载并显示
- Android Http基础:图片下载并显示和WebView的应用
- android 显示gif图片
- Android 显示Gif
- android显示gif图片
- Android显示GIF图片
- Android显示GIF动画
- android activity显示gif
- android显示gif图片
- Android显示GIF动画
- android 显示gif图片
- android显示GIF图片
- Android显示GIF动画
- Android显示gif图片
- Android显示GIF图片
- android 显示gif图片
- C++语言中用程序实现读入一个包含标点符号的字符串,将标点符号去除后输出字符串剩余的部分
- 数据结构——归并排序算法
- oracle中的sql%rowcount
- ACdream 1073
- Managing Projects from the Command Line(android官网文档)
- [Android开发]Gif图片下载和显示
- 如何提高代码质量
- scheme心得(3) 尾调用/尾递归与CPS
- CentOS6.6下编译jsoncpp
- Java 数据库操作
- shader之旅-7-平面阴影(planar shadow)
- 2015百度之星资格赛解题报告
- C语言预处理命令总结
- JDK/ADT Android开发环境搭建 (二)