package cc.duduhuo.gifviewdemo.view;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Movie;
import android.os.Build;
import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.view.View;
/**
* =======================================================
* 作者:liying - liruoer2008@yeah.net
* 日期:2017/8/19 20:09
* 版本:1.0
* 描述:自定义显示Gif图片的View
* 备注:
* =======================================================
*/
public class GifView extends View {
private static final int DEFAULT_MOVIE_VIEW_DURATION = 1000;
private int mMovieResourceId;
private Movie mMovie;
private long mMovieStart;
private int mCurrentAnimationTime;
/**
* 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;
private boolean mVisible = true;
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);
init();
}
private void init() {
/*
* Starting from HONEYCOMB(Api Level:11) 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);
}
}
public void setGifResource(int movieResourceId) {
this.mMovieResourceId = movieResourceId;
mMovie = Movie.decodeStream(getResources().openRawResource(mMovieResourceId));
requestLayout();
}
public int getGifResource() {
return this.mMovieResourceId;
}
public void play() {
if (this.mPaused) {
this.mPaused = false;
/*
* Calculate new movie start time, so that it resumes from the same
* frame.
*/
mMovieStart = SystemClock.uptimeMillis() - mCurrentAnimationTime;
invalidate();
}
}
public void pause() {
if (!this.mPaused) {
this.mPaused = true;
invalidate();
}
}
public boolean isPaused() {
return this.mPaused;
}
public boolean isPlaying() {
return !this.mPaused;
}
@Override
protected 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 (movieWidth > maximumWidth) {
scaleH = (float) movieWidth / (float) maximumWidth;
}
}
/*
* calculate vertical scaling
*/
float scaleW = 1f;
int measureModeHeight = MeasureSpec.getMode(heightMeasureSpec);
if (measureModeHeight != MeasureSpec.UNSPECIFIED) {
int maximumHeight = MeasureSpec.getSize(heightMeasureSpec);
if (movieHeight > maximumHeight) {
scaleW = (float) movieHeight / (float) maximumHeight;
}
}
/*
* calculate overall scale
*/
mScale = 1f / Math.max(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());
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
/* Calculate mLeft / mTop for drawing in center */
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);
}
}
}
/**
* Invalidates view only if it is mVisible.
* <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_MOVIE_VIEW_DURATION;
}
mCurrentAnimationTime = (int) ((now - mMovieStart) % dur);
}
/**
* Draw current GIF frame
*/
private void drawMovieFrame(Canvas canvas) {
mMovie.setTime(mCurrentAnimationTime);
canvas.save();
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();
}
/**
* get gif width
*
* @return width
*/
public int getGifWidth() {
return mMovie.width();
}
/**
* get gif height
*
* @return height
*/
public int getGifHeight() {
return mMovie.height();
}
@SuppressLint("NewApi")
@Override
protected void onVisibilityChanged(@NonNull 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();
}
}
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
GifViewDemo.zip (82个子文件)
GifViewDemo
.gitignore 118B
app
.gitignore 7B
app-debug.apk 2.16MB
build.gradle 937B
src
androidTest
java
cc
duduhuo
gifviewdemo
ExampleInstrumentedTest.java 748B
main
AndroidManifest.xml 842B
res
mipmap-xhdpi
ic_launcher_round.png 6KB
ic_launcher.png 5KB
mipmap-mdpi
ic_launcher_round.png 2KB
ic_launcher.png 2KB
layout
activity_gif.xml 571B
activity_main.xml 1KB
mipmap-xxhdpi
ic_launcher_round.png 10KB
ic_launcher.png 8KB
drawable
gif4.gif 559KB
gif2.gif 625KB
gif3.gif 511KB
gif1.gif 35KB
mipmap-hdpi
ic_launcher_round.png 4KB
ic_launcher.png 3KB
mipmap-xxxhdpi
ic_launcher_round.png 14KB
ic_launcher.png 10KB
values
strings.xml 74B
colors.xml 208B
styles.xml 536B
java
cc
duduhuo
gifviewdemo
MainActivity.java 1KB
view
GifView.java 7KB
GifActivity.java 2KB
test
java
cc
duduhuo
gifviewdemo
ExampleUnitTest.java 400B
libs
proguard-rules.pro 922B
app.iml 11KB
settings.gradle 15B
build.gradle 498B
GifViewDemo.iml 865B
gradlew 5KB
gradlew.bat 2KB
gradle.properties 730B
.gradle
3.3
taskArtifacts
fileSnapshots.bin 4.15MB
taskArtifacts.lock 17B
fileHashes.bin 145KB
taskArtifacts.bin 143KB
tasks
_app_compileDebugJavaWithJavac
localClassSetAnalysis
localClassSetAnalysis.lock 17B
localClassSetAnalysis.bin 49KB
localJarClasspathSnapshot
localJarClasspathSnapshot.bin 20KB
localJarClasspathSnapshot.lock 17B
.idea
misc.xml 6KB
encodings.xml 159B
libraries
support_compat_26_0_0_alpha1.xml 598B
exposed_instrumentation_api_publish_0_5.xml 636B
hamcrest_library_1_3.xml 540B
constraint_layout_solver_1_0_2.xml 343B
animated_vector_drawable_26_0_0_alpha1.xml 628B
javawriter_2_1_1.xml 521B
constraint_layout_1_0_2.xml 410B
jsr305_2_0_1.xml 330B
javax_inject_1.xml 511B
support_core_ui_26_0_0_alpha1.xml 601B
support_core_utils_26_0_0_alpha1.xml 610B
support_vector_drawable_26_0_0_alpha1.xml 625B
espresso_idling_resource_2_2_2.xml 618B
junit_4_12.xml 477B
rules_0_5.xml 546B
support_fragment_26_0_0_alpha1.xml 604B
javax_annotation_api_1_2.xml 569B
support_v4_26_0_0_alpha1.xml 586B
runner_0_5.xml 549B
hamcrest_core_1_3.xml 526B
hamcrest_integration_1_3.xml 561B
espresso_core_2_2_2.xml 585B
appcompat_v7_26_0_0_alpha1.xml 592B
support_annotations_26_0_0_alpha1.xml 542B
support_media_compat_26_0_0_alpha1.xml 616B
workspace.xml 191KB
gradle.xml 626B
copyright
profiles_settings.xml 76B
runConfigurations.xml 564B
compiler.xml 709B
markdown-navigator
profiles_settings.xml 106B
modules.xml 359B
gradle
wrapper
gradle-wrapper.properties 236B
gradle-wrapper.jar 52KB
local.properties 510B
共 82 条
- 1
资源评论
- JinYouXingFu2017-10-11不错不错啊
李颖1750
- 粉丝: 12
- 资源: 22
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功