您的位置:首页 > 移动开发 > Android开发

Android APIDemos 研读之一:android.graphics.Movie

2013-10-17 15:12 435 查看
原创:http://blog.csdn.net/sharetop/article/details/5268419

如何在Android中显示GIF动画,有很多方法,比如可以使用J2ME平台上那个解码工具类,纯java的,拿来即可。

但是其实Android还是为我们提供了一个更为方便的工具:android.graphics.Movie。

参考例子在ApiDemos中的BitmapDecode中。

下面我只是简单地用它来实现一个自己的GIFView,以方便在各种需要使用GIF动画的场合使用。

为了简单,我让GIFView extends ImageView罢了。它在布局中的描述如下:

[xhtml] view
plaincopy

<cn.sharetop.android.view.GIFView  

    android:id="@+id/gif"  

    android:layout_gravity="center_horizontal"  

    android:layout_width="278px"  

    android:layout_height="183px"  

    android:scaleType="fitXY"  

    app:gif="@drawable/a"  

    android:src="@drawable/a"  

    />  

与ImageView唯一的区别在于我加了一个gif属性,与src属性的值是一样的。不过它们需要同时存在,不可省略其中之一(后面我会说明为什么)。

注意因为gif属性,所以别忘了那个attr.xml中也要加上:

[xhtml] view
plaincopy

<resources>  

    <declare-styleable name="GIFView">  

        <attr name="gif" format="reference"  />  

    </declare-styleable>  

</resources>  

然后是代码,没几行的:

[java] view
plaincopy

public class GIFView extends ImageView {  

    private static final String TAG="GIFView";  

     

    private Movie mMovie;     

    private long mMovieStart;  

     

     

    //此处省略几个构造函数  

    //......  

    //主要的构造函数  

    public GIFView(Context context, AttributeSet attrs, int defStyle) {  

        super(context, attrs, defStyle);  

        // TODO Auto-generated constructor stub  

         

        mMovie=null;  

        mMovieStart=0;  

         

        //从描述文件中读出gif的值,创建出Movie实例  

        TypedArray a = context.obtainStyledAttributes(attrs,  

                R.styleable.GIFView, defStyle, 0);  

         

        int srcID=a.getResourceId(R.styleable.GIFView_gif, 0);  

        if(srcID>0){  

            InputStream is = context.getResources().openRawResource(srcID);  

            mMovie = Movie.decodeStream(is);  

        }  

         

        a.recycle();  

    }  

    //主要的工作是重载onDraw  

    @Override  

    protected void onDraw(Canvas canvas) {  

        // TODO Auto-generated method stub  

        //super.onDraw(canvas);  

         

        //当前时间  

        long now = android.os.SystemClock.uptimeMillis();  

        //如果第一帧,记录起始时间  

        if (mMovieStart == 0) {   // first time  

              mMovieStart = now;  

        }  

        if (mMovie != null) {  

                  //取出动画的时长  

            int dur = mMovie.duration();  

                  if (dur == 0) {  

                      dur = 1000;  

                  }  

                  //算出需要显示第几帧  

            int relTime = (int)((now - mMovieStart) % dur);  

           

                  //Log.d(TAG,"---onDraw..."+mMovie.toString()+",,,,"+relTime);  

             //设置要显示的帧,绘制即可  

                  mMovie.setTime(relTime);  

            mMovie.draw(canvas,0,0);  

                  invalidate();  

        }         

    }  

         

}  

代码中已有注释,就不多说了。我的理解是Movie其实管理着GIF动画中的多个帧,只需要通过 setTime() 一下就可以让它在draw()的时候绘出相应的那帧图像。

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

最后,说一下为什么src与gif要同时存在了,因为我这个GIFView很简单,没有自己去onMeasure,所以要借助src让ImageView去计算它的尺寸和布局之类的事情。

只是在onDraw的时候,不显示src而已。

如果感兴趣的同学可以自己完善这个GIFView,比如以下两点:

1. 只需要一个gif属性,不要src了,或者直接使用src属性?

2. 如果在xml中没有指定gif/src的值,增加一些方法让用户可以通过代码设置gif和src的值

 

[补充]

 

刚才又觉得这段代码有修正的必要:

 

1. 关于如何直接使用src这个属性,仍是修改attr.xml中,这样即可:

 

[xhtml] view
plaincopy

<resources>  

    <declare-styleable name="GIFView">  

        <attr name="android:src" />  

    </declare-styleable>  

</resources>  

 

然后在main.xml中就不再需要gif这个属性,直接用src就可以了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android