摘自
2010/06/10, 16:48
用Movie来播放gif动画时,开始用android的SDK自带的ApiDemos里的gif图片是正常的,后来发现用上自己的gif图片就出现了花屏的问题。
也许两张gif图片之间有什么设置差别造成的呢?于是我用Adobe ImageReady打开了能正常显示的和出现花屏的gif图片进行对比。
结果找到来解决问题的方法(也许还有别的更好的方法)。
如下图:
右击动画帧,然后选择“恢复为背景”。
2010/06/10, 16:21
目前android.graphics.Movie类在SDK文档中还没有任何的说明。
Movie类是可以用来播放gif动画,跟电影的原理一样都是通过播放连续的帧,利用视觉暂留得到运动的效果。这倒使我想到了AnimationDrawable类,这两者看起来差不多,于是尝试用Movie类来播放AnimationDrawable定义的动画,失败了。
1,原理
通过不停的重新绘制来换帧。
2,方法说明
decodeByteArray(byte[] data, int offset, int length)
decodeFile(String pathName)
decodeStream(InputStream is)
三种不同的静态方法来获取Movie对象。三种方式的原理其实都一样,都是读入字节流来解码创建Movie对象。decodeByteArray是从一个已经存在的字节数组中创建,decodeFile是从一个文件读入字节流来创建。
draw(Canvas canvas, float x, float y)
draw(Canvas canvas, float x, float y, Paint paint)
绘制动画帧。
它们其实还是调用Canvas的drawBitmap来绘制帧的。
duration()
动画持续的时间,也就是完成一次动画播放的时间。
isOpaque()
是不是不透明
setTime(int relativeMilliseconds)
设置相对本次播放第一帧时间,根据这个时间来决定显示第几帧。
例如:
int relTime=(int)((now – moviestart)%movie.duration());
now:系统当前时刻
moviestart:动画开始的时间
movie.duration:动画持续的时间,也就是完成一次动画的时间
注意这是取余操作,这才能算出当前这次重复播放的第一帧的时间。
height() 高
width() 宽
3,实例
public class Main extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
private static class SampleView extends View {
private Movie mMovie;
private long mStart=0;
private int relTime;
public SampleView(Context context) {
super(context);
mMovie = Movie.decodeStream(context.getResources().openRawResource(R.drawable.pig));
}
@Override protected void onDraw(Canvas canvas) {
long now=android.os.SystemClock.uptimeMillis();
if(mStart==0) mStart = now;
int dur=mMovie.duration();
if(dur==0) dur=1000;
relTime=(int)((now-mStart)%dur);
mMovie.setTime(relTime);
canvas.drawColor(Color.WHITE);
mMovie.draw(canvas, 0,0);
this.invalidate();
}
}
}
2010/06/08, 14:11
对android的Animation的初级理解,Moandroid的下面三篇文章已经讲解的很清楚了。
http://www.moandroid.com/?p=790
http://www.moandroid.com/?p=808
http://www.moandroid.com/?p=812
1,android的动画分为两种:Tween Animation和Frame Animation。
这个两种动画的原理也是不相同的,他们的包在SDK中的位置也是不一样。Tween动画的包在android.view.animation下,Frame动画的包在android.graphics.drawable下。
2,这两种动画的不同在于:
Frame动画是对预先设置好的图片进行依次显示,以产生动画效果,就象电影那样。
Tween动画则是要把它作用于某个对象上,如view组件,drawable。例如有个Button,想让它产生转换位置的动画效果,那么就要创建一个TranslateAnimation对象,然后把它作用于这个Button上。
3,那么TranslateAnimation是如何才能作用与Button上呢?
View对象都有一个setAnimation方法就是来和动画关联起来产生动画效果。那么如果才能让drawable也产生动画呢,drawable可没有setAnimation方法来调用的。
android的View组件其实也是调用android.graphics.*包里的相关工具绘制出来的,也就是所View产生动画的原理同样可以让drawable产生动画。
4,Tween动画的原理
View组件是由Canvas来绘制出来的。
Canvas类包含一个Martix,在绘制时会先进行一次矩阵运算,把运算的的结果显示在Canvas上。这时图片就产生了变动,图形变换通过仿射矩阵实现。图形变换是图形学中的基本知识。简单来说就是,每种变换都是一次矩阵运算。
Animation类有有个getTransformation(long currentTime, Transformation outTransformation)方法来获取此动画当前时刻的Transformation,它记录了仿射矩阵 Matrix,动画每触发一次,会对原来的矩阵做一次运算。然后通过Transformation的getMatrix()方法把此Martix给提取出来。
然后让Cavnas运行此Martix,通过Canvas的concat(Matrix matrix)方法来替换当前的martix。
到这里View按Animation的变换了一次,接下来就是要不停的从Animation中获取Martix(如何变换的信息),Canvas不断的改变,就产生的动画效果。
5,让drawable产生Tween动画的例子
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
| public class Main extends Activity {
private Animation ani ;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new myView(this));
}
private class myView extends View
{
private Drawable da;
private ScaleAnimation sa;
private int i=0;
public myView(Context context) {
super(context);
// TODO Auto-generated constructor stub
//创建drawable
da =getResources().getDrawable(R.drawable.google);
da.setBounds(0, 0,da.getIntrinsicWidth(), da.getIntrinsicHeight());
//创建一个Animation,并设置。
sa = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f);
sa.setDuration(3000);
sa.setRepeatCount(1);
sa.setRepeatMode(2);
sa.startNow();
}
@Override
protected void onDraw(Canvas canvas)
{
//获取Transformation
Transformation tf = new Transformation();
sa.getTransformation(AnimationUtils.currentAnimationTimeMillis(), tf);
canvas.drawColor(Color.BLACK);
//获取Matrix并设置到canvas
canvas.concat(tf.getMatrix());
da.draw(canvas);
//这个是来设置不停的获取Martix来重绘
invalidate();
}
}
} |
2010/05/19, 12:25
我们可以通过putExtra方法向Intent中添加数据。
在Intent类中有很多重载的putExtra方法。在android中Intent是通过Bundle类型来传递数据的,这些重载的方法获取到参数后也是转换成Bundle类型后才传输的。
例如其中一个方法的实现:
public Intent putExtra(String name, byte value) {
if (mExtras == null) {
mExtras = new Bundle();
}
mExtras.putByte(name, value);
return this;
}
如果想传多组值,可以多次调用putExtra方法:
intent1.putExtra(“name”,”liu”);
intent1.putExtra(“city”,”beijing”);
当然可以直接使用Bundle容器,然后调用 putExtras(Bundle extras)