百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

Android开发之利用graphics.Movie类显示GIF动画

toyiye 2024-05-19 19:35 22 浏览 0 评论

Android开发之利用Movie类显示GIF动画

在应用程序开发中,人机交互很重要,往往在应用中加入一个小动画,就能够让你的应用程序显得更加生动而不乏味。现在我们来列举一个实例,如何在安卓手机中显示GIF动画图片。

这个实例主要用的是android中的android.,这是android提供给我们的一个非常方便的工具。

首先,重写控件View,自定义一个展示gif图的GifView,代码如下:

[java]

package net.myprojexc.gif.view;


import net.myprojexc.gif.R;

import android.annotation.SuppressLint;

import android.content.Context;

import android.content.res.TypedArray;

import android.graphics.Canvas;

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, 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();

}


}

Movie其实管理着GIF动画中的多个帧,只需要通过 setTime() 一下就可以让它在draw()的时候绘出相应的那帧图

像。通过当前时间与duration之间的换算关系,是很容易实现GIF动起来的效果。

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

[html]

<?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" >


<net.myprojexc.gif.view.GifView

android:id="@+id/gif1"

android:layout_width="100dp"

android:layout_height="100dp"

android:layout_gravity="center_horizontal"

android:enabled="false" />


<net.myprojexc.gif.view.GifView

android:id="@+id/gif2"

android:layout_width="200dp"

android:layout_height="200dp"

android:layout_gravity="center_horizontal"

android:enabled="false" />

</LinearLayout>

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

[java]

package net.myprojexc.gif;

import net.myprojexc.gif.view.GifView;

import android.app.Activity;

import android.os.Bundle;


public class Gif extends Activity {

private GifView gif1, gif2;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

gif1 = (GifView) findViewById(R.id.gif1);

// 设置背景gif图片资源

gif1.setMovieResource(R.raw.kitty);

gif2 = (GifView) findViewById(R.id.gif2);

gif2.setMovieResource(R.raw.b);

// 设置暂停

// gif2.setPaused(true);

}


}

注意:与ImageView和其他View唯一的区别在于加了一个gif属性。

[html]

<?xml version="1.0" encoding="utf-8"?>

<resources>

<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>

</resources>

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码