Android加载Gif动画如何实现?相信大家都很好奇,本文就为大家揭晓,内容如下
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <com.example.gifdemo.GifView android:id="@+id/gif1" android:layout_width="100dp" android:layout_height="100dp" android:layout_gravity="center_horizontal" android:enabled="false" /> </LinearLayout>
<declare-styleable name="GifView"> <attr name="gif" format="reference" /> <attr name="paused" format="boolean" /> </declare-styleable>
主界面
package com.example.gifdemo; import android.app.Activity; import android.os.Bundle; public class MainActivity extends Activity { private GifView gif1; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); gif1 = (GifView) findViewById(R.id.gif1); // 设置背景gif图片资源 gif1.setMovieResource(R.raw.red); } }
自定义view
package com.example.gifdemo; import android.annotation.SuppressLint; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Movie; import android.os.Build; import android.util.AttributeSet; import android.view.View; public class GifView extends View { /** * 默认为1秒 */ private static final int DEFAULT_MOVIE_DURATION = 1000; private int mMovieResourceId; private Movie mMovie; private long mMovieStart; private int mCurrentAnimationTime = 0; private float mLeft; private float mTop; private float mScale; private int mMeasuredMovieWidth; private int mMeasuredMovieHeight; private boolean mVisible = true; private volatile boolean mPaused = false; /** * 构造函数 */ public GifView(Context context) { this(context, null); } public GifView(Context context, AttributeSet attrs) { this(context, attrs,0); } public GifView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); setViewAttributes(context, attrs, defStyle); setBackgroundColor(Color.parseColor("#FFB6C1")); } @SuppressLint("NewApi") private void setViewAttributes(Context context, AttributeSet attrs, int defStyle) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { setLayerType(View.LAYER_TYPE_SOFTWARE, null); } // 从描述文件中读出gif的值,创建出Movie实例 final TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.GifView); mMovieResourceId = array.getResourceId(R.styleable.GifView_gif, -1); mPaused = array.getBoolean(R.styleable.GifView_paused, false); array.recycle(); if (mMovieResourceId != -1) { mMovie = Movie.decodeStream(getResources().openRawResource( mMovieResourceId)); } } /** * 设置gif图资源 */ public void setMovieResource(int movieResId) { this.mMovieResourceId = movieResId; mMovie = Movie.decodeStream(getResources().openRawResource( mMovieResourceId)); requestLayout(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (mMovie != null) { //gif动画的宽度、高度 int movieWidth = mMovie.width(); int movieHeight = mMovie.height(); //控件的宽度 int maximumWidth = MeasureSpec.getSize(widthMeasureSpec); //gif图片宽/控件宽 float scaleW = (float) movieWidth / (float) maximumWidth; mScale = 1f / scaleW; mMeasuredMovieWidth = maximumWidth; mMeasuredMovieHeight = (int) (movieHeight * mScale); setMeasuredDimension(mMeasuredMovieWidth, mMeasuredMovieHeight); } else { setMeasuredDimension(getSuggestedMinimumWidth(), getSuggestedMinimumHeight()); } } // @Override // protected void onLayout(boolean changed, int l, int t, int r, int b) { // super.onLayout(changed, l, t, r, b); // mLeft = (getWidth() - mMeasuredMovieWidth) / 2f; // mTop = (getHeight() - mMeasuredMovieHeight) / 2f; // mVisible = getVisibility() == View.VISIBLE; // } @Override protected void onDraw(Canvas canvas) { if (mMovie != null) { if (!mPaused) { updateAnimationTime(); drawMovieFrame(canvas); invalidateView(); } else { drawMovieFrame(canvas); } } } private void updateAnimationTime() { long now = android.os.SystemClock.uptimeMillis(); // 如果第一帧,记录起始时间 if (mMovieStart == 0) { mMovieStart = now; } // 取出动画的时长 int dur = mMovie.duration(); if (dur == 0) { dur = DEFAULT_MOVIE_DURATION; } // 算出需要显示第几帧 mCurrentAnimationTime = (int) ((now - mMovieStart) % dur); } 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") private void invalidateView() { if (mVisible) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { postInvalidateOnAnimation(); } else { invalidate(); } } } // --------------------以下方法未调用------------------------------------/ 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; if (!paused) { mMovieStart = android.os.SystemClock.uptimeMillis() - mCurrentAnimationTime; } invalidate(); } public boolean isPaused() { return this.mPaused; } @SuppressLint("NewApi") @Override public void onScreenStateChanged(int screenState) { super.onScreenStateChanged(screenState); mVisible = screenState == SCREEN_STATE_ON; invalidateView(); } @SuppressLint("NewApi") @Override protected void onVisibilityChanged(View changedView, int visibility) { super.onVisibilityChanged(changedView, visibility); mVisible = visibility == View.VISIBLE; invalidateView(); } @Override protected void onWindowVisibilityChanged(int visibility) { super.onWindowVisibilityChanged(visibility); mVisible = visibility == View.VISIBLE; invalidateView(); } // --------------------------------------------------------/ }
源码下载:http://xiazai.jb51.net/201610/yuanma/AndroidGifDemo(jb51.net).rar
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
本文向大家介绍android实现加载动画对话框,包括了android实现加载动画对话框的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了android实现加载动画对话框的具体代码,供大家参考,具体内容如下 先来两张效果图 自定义对话框: 在layout文件夹下建立progress_dialog.xml 在res文件夹下建立anim文件夹,然后在里面建立frame.xml 动画是由一张一
问题内容: 我正在尝试在JLabel中加载动画GIF。 尽管这可行: 另一方面,这不是,我也不想从URL获取GIF,因为我已经有了GIF。加载结果仅显示GIF的第一帧: 我想一定是有原因的,但是我找不到。 谢谢!亚历克斯 问题答案: 您可以尝试像这样加载GIF文件: 或使用,如果你的背景是静态的。
本文向大家介绍Android自定义加载控件实现数据加载动画,包括了Android自定义加载控件实现数据加载动画的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了Android自定义加载控件,第一次小人跑动的加载效果眼前一亮,相比传统的PrograssBar高大上不止一点,于是走起,自定义了控件LoadingView去实现动态效果,可直接在xml中使用,具体实现如下 2. xml布局文件
问题内容: 在iOS Swift中,我很难将动画GIF从设备图片库加载到UIImageView或从中创建.gif文件。如果它是服务器上的文件或正确在应用程序中,则显示动画GIF没问题。但是,当我从照片库中加载它时,会丢失动画。我找到了一些Objective- C解决方案,并试图将它们转换为Swift,但是没有任何运气。 这是我到目前为止的内容: 理想情况下,我想将照片库图像保存到服务器上的gif文
本文向大家介绍Android仿支付宝笑脸刷新加载动画的实现代码,包括了Android仿支付宝笑脸刷新加载动画的实现代码的使用技巧和注意事项,需要的朋友参考一下 看到支付宝的下拉刷新有一个笑脸的动画,因此自己也动手实现一下。效果图如下: 一、总体思路 1、静态部分的笑脸。 这一部分的笑脸就是一个半圆弧,加上两颗眼睛,这部分比较简单,用于一开始的展示。 2、动态笑脸的实现。 2.1、先是从底部有一个圆
1.4. GIF动画 下面的程序会演示Go语言标准库里的image这个package的用法,我们会用这个包来生成一系列的bit-mapped图,然后将这些图片编码为一个GIF动画。我们生成的图形名字叫利萨如图形(Lissajous figures),这种效果是在1960年代的老电影里出现的一种视觉特效。它们是协振子在两个纬度上振动所产生的曲线,比如两个sin正弦波分别在x轴和y轴输入会产生的曲线。