服务器之家

服务器之家 > 正文

Android显示GIF图片实例代码

时间:2022-02-16 16:28     来源/作者:poclist

最近.一个朋友跟我说想,我给她弄个闹钟APP软件...功能其实很简单...只需要弄个简单的闹钟.自己设计设计时间.然后时间到了的时候,闹铃放的声音是男朋友录制好的声音...于是就开始整了....

第一次做这种的时候.我想把首页界面做成一个GIF动画特效的.这样看起来可爱点...适合妹子用,于是就有了下面这个效果图

Android显示GIF图片实例代码

上代码

ndroid中的Android.graphics.Movie 这个类,这是android提供给我们的一个非常方便的工具。
首先,重写控件View,自定义一个展示gif图的GifView
Movie其实管理着GIF动画中的多个帧,只需要通过 setTime() 一下就可以让它在draw()的时候绘出相应的那帧图像。通过当前时间与duration之间的换算关系,是很容易实现GIF动起来的效果。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
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, R.styleable.CustomTheme_gifViewStyle);
 }
 public GifView(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) {
 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, defStyle, R.style.Widget_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图资源
 *
 * @param movieResId
 */
 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();
 }
 /**
 * 设置暂停
 *
 * @param paused
 */
 public void setPaused(boolean paused) {
 this.mPaused = paused;
 if (!paused) {
  mMovieStart = android.os.SystemClock.uptimeMillis()
   - mCurrentAnimationTime;
 }
 invalidate();
 }
 /**
 * 判断gif图是否停止了
 *
 * @return
 */
 public boolean isPaused() {
 return this.mPaused;
 }
 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 if (mMovie != null) {
  int movieWidth = mMovie.width();
  int movieHeight = mMovie.height();
  int maximumWidth = MeasureSpec.getSize(widthMeasureSpec);
  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);
  }
 }
 }
 @SuppressLint("NewApi")
 private void invalidateView() {
 if (mVisible) {
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
  postInvalidateOnAnimation();
  } else {
  invalidate();
  }
 }
 }
 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")
 @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();
 }
 
}

其次,在xml布局文件中,把这个view定义进去,代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:background="#ffffff"
  android:gravity="center"
  android:orientation="vertical"
 >
 
 <com.example.alarmtest.GifView
 android:id="@+id/gif1"
 android:layout_width="300dp"
 android:layout_height="300dp"
 android:layout_gravity="center_horizontal"
 android:enabled="false"/>
 <Button
 android:id="@+id/bu"
 android:text="进入"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_gravity="center_horizontal"/>
 
</LinearLayout>

最后,在MainActivity中的使用,代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
public class FirstActivity extends Activity {
 private GifView gif;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_first);
 gif = (GifView) findViewById(R.id.gif1);
 // 设置背景gif图片资源
 gif.setMovieResource(R.raw.a123);
 }
}

Styles.xml

?
1
2
3
4
5
6
7
8
<declare-styleable name="GifView">
 <attr name="gif" format="reference" />
 <attr name="paused" format="boolean" />
 </declare-styleable>
 <declare-styleable name="CustomTheme">
 <attr name="gifViewStyle" format="reference" />
 </declare-styleable>
 <style name="Widget_GifView"></style>
 

raw是res下面的一个文件放的是GIF动画图噢

我这里放了一个动画图 跟一个 音乐文件,因为我要做的是一个有声音的闹铃

Android显示GIF图片实例代码

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对服务器之家的支持。

原文链接:https://blog.csdn.net/bfboys/article/details/53183171

标签:

相关文章

热门资讯

蜘蛛侠3英雄无归3正片免费播放 蜘蛛侠3在线观看免费高清完整
蜘蛛侠3英雄无归3正片免费播放 蜘蛛侠3在线观看免费高清完整 2021-08-24
2022年最旺的微信头像大全 微信头像2022年最新版图片
2022年最旺的微信头像大全 微信头像2022年最新版图片 2022-01-10
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
返回顶部