自定义View实现米老鼠时钟

来源:互联网 发布:p2p网络投资理财 编辑:程序博客网 时间:2024/04/30 16:57

先看效果图,米老鼠的两个手分别指向时钟和分钟,然后米老鼠的脚在一秒执行一次动画操作。

分析完之后就先实现gif的播放,

如果实现gif的播放,就想着使用SurfaceView实现每格一秒循环一次贞动画。于是就需要8张贞图片,然后在surfaceView的125ms时间内播放一个贞,最后1000ms也就是1s播放了一次米老鼠跺脚的行为。代码如下:

private  int count=0;
/******/

while (mIsDrawing) {    long start = System.currentTimeMillis();    draw(count);    //0-7时候count++;到8时候count=0;    if (count<7){        count++;    }else {        count=0;    }    long end = System.currentTimeMillis();    try {        if (end - start < 125) {            Thread.sleep(125 - (end - start));        }    } catch (InterruptedException e) {        e.printStackTrace();    }
分析完了播放1s跺脚动画之后就需要实现两个手的绘制。
首先需要的就是测量中心点和半径长度:
int widthSpecMode=MeasureSpec.getMode(widthMeasureSpec);int widthSpecSize=MeasureSpec.getSize(widthMeasureSpec);int heightSpecMode=MeasureSpec.getMode(heightMeasureSpec);int heightSpecSize=MeasureSpec.getSize(heightMeasureSpec);if (widthSpecMode==MeasureSpec.AT_MOST||heightSpecMode==MeasureSpec.AT_MOST){    width = Math.min(getMeasuredHeight() , getMeasuredWidth() );    setMeasuredDimension(width, width);}else {    width=Math.min(widthSpecSize,heightSpecSize);    setMeasuredDimension(width,width);}//中心点mCenter=width/2;//半径mRadius=mCenter-getPaddingLeft()-getPaddingRight();中心点是width/2和getMeasuredHeight() /2的中心坐标
半径就是mRadius=mCenter-getPaddingLeft()-getPaddingRight();
测量完之后确定时钟和分钟的图片长度
//时分秒的长度hDimension = mRadius * 2 / 3 ;mDimension = mRadius *4/5;
最后要绘制这两个过程了:
Calendar c = Calendar.getInstance();int hour = c.get(Calendar.HOUR_OF_DAY);Log.e("hour",hour+"");int minute = c.get(Calendar.MINUTE);Log.e("minute",minute+"");//3个角度int minutefloat = minute * 360/ 60 ;Log.e("minutefloat",minutefloat+"");int hourfloat = ((hour % 12)) * 360/ 12 +minute*360/60/12;Log.e("hourfloat",hourfloat+"");
上述代码是计算时钟和分钟对应的角度,当我们计算完了角度之后就可以使用
mCanvas.save();
mCanvas.rotate
mCanvas.restore();
实现画布旋转和绘制图层叠加。
下面分别是绘制分钟,背景和时钟。
private void drawminite(int angle) {    mCanvas.save();    //以中心坐标旋转画布画分钟手势图    mCanvas.rotate(angle, mCenter, getMeasuredHeight() / 2);    int imgsWidth = (int) (mRadius/3);    Rect rectm = new Rect(mCenter - imgsWidth / 2, getMeasuredHeight()/2  - mDimension, mCenter + imgsWidth / 2, getMeasuredHeight() / 2 );    mCanvas.drawBitmap(mImgsBitmap[1], null, rectm, null);    mCanvas.restore();}private void drawBg(int count) {    mCanvas.drawColor(Color.TRANSPARENT);    mCanvas.drawBitmap(mBgBitmap[count],null,new Rect(0,getMeasuredHeight()/2-getMeasuredWidth()/2,getMeasuredWidth(),getMeasuredHeight()/2+getMeasuredWidth()/2),null);}private void drawhour(int angle) {    mCanvas.rotate(angle,mCenter,getMeasuredHeight()/2);    //秒钟宽度    int imgsWidth = (int) (mRadius/3);    Rect recth = new Rect(mCenter - imgsWidth / 2, getMeasuredHeight()/2  - hDimension, mCenter + imgsWidth / 2, getMeasuredHeight()/2);    mCanvas.drawBitmap(mImgsBitmap[0], null, recth, null);}
所有的绘制过程就这样绘制完毕,当然所有的绘制都应该在SurfaceView的一个绘制框架内完成。下面贴出完整的代码:
package com.example.admin.customclock.customView;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Rect;import android.text.format.Time;import android.util.AttributeSet;import android.util.Log;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.view.View;import com.example.admin.customclock.R;import java.util.Calendar;/** * Created by admin on 2016/1/20. */public class ClockView extends SurfaceView implements SurfaceHolder.Callback, Runnable {    private SurfaceHolder mHolder;    private Canvas mCanvas;    private boolean mIsDrawing;    private Thread t;    private int mRadius;    //时分秒图片资源    private int[] mclockimgs = new int[]{            R.drawable.hhand,            R.drawable.mhand,            R.drawable.shand};    //时分秒的长度    private int hDimension;    private int mDimension;    private int sDimension;    private int width;    //图片资源转Bitmap    private Bitmap[] mImgsBitmap=new Bitmap[3];    //中心点    private int mCenter;    private int mPadding;    private Bitmap[] mBgBitmap=new Bitmap[8];    private int[] mBgImages = new int[]{            R.drawable.clock_1,            R.drawable.clock_2,            R.drawable.clock_3,            R.drawable.clock_4,            R.drawable.clock_5,            R.drawable.clock_6,            R.drawable.clock_7,            R.drawable.clock_8    };    private  int count=0;    public ClockView(Context context) {        this(context, null);    }    public ClockView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public ClockView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        initView();    }    private void initView() {        mHolder = getHolder();        mHolder.addCallback(this);        setFocusable(true);        setFocusableInTouchMode(true);        this.setKeepScreenOn(true);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int widthSpecMode=MeasureSpec.getMode(widthMeasureSpec);        int widthSpecSize=MeasureSpec.getSize(widthMeasureSpec);        int heightSpecMode=MeasureSpec.getMode(heightMeasureSpec);        int heightSpecSize=MeasureSpec.getSize(heightMeasureSpec);        if (widthSpecMode==MeasureSpec.AT_MOST||heightSpecMode==MeasureSpec.AT_MOST){            width = Math.min(getMeasuredHeight() , getMeasuredWidth() );            setMeasuredDimension(width, width);        }else {            width=Math.min(widthSpecSize,heightSpecSize);            setMeasuredDimension(width,width);        }        //中心点        mCenter=width/2;        //半径        mRadius=mCenter-getPaddingLeft()-getPaddingRight();        //时分秒的长度        hDimension = mRadius * 2 / 3 ;        mDimension = mRadius *4/5;    }    @Override    public void surfaceCreated(SurfaceHolder holder) {        for (int i=0;i<8;i++){            mBgBitmap[i] = BitmapFactory.decodeResource(getResources(), mBgImages[i]);        }        mImgsBitmap = new Bitmap[3];        for (int i = 0; i < 3; i++) {            mImgsBitmap[i] = BitmapFactory.decodeResource(getResources(), mclockimgs[i]);        }        mIsDrawing = true;        t = new Thread(this);        t.start();    }    @Override    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {    }    @Override    public void surfaceDestroyed(SurfaceHolder holder) {        mIsDrawing = false;    }    @Override    public void run() {        while (mIsDrawing) {            long start = System.currentTimeMillis();            draw(count);            //0-7时候count++;到8时候count=0;            if (count<7){                count++;            }else {                count=0;            }            long end = System.currentTimeMillis();            try {                if (end - start < 125) {                    Thread.sleep(125 - (end - start));                }            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }    private void draw(int count) {        try {            mCanvas = mHolder.lockCanvas();            if (mCanvas != null) {                //...                Calendar c = Calendar.getInstance();                int hour = c.get(Calendar.HOUR_OF_DAY);                Log.e("hour",hour+"");                int minute = c.get(Calendar.MINUTE);                Log.e("minute",minute+"");                //3个角度                int minutefloat = minute * 360/ 60 ;                Log.e("minutefloat",minutefloat+"");                int hourfloat = ((hour % 12)) * 360/ 12 +minute*360/60/12;                Log.e("hourfloat",hourfloat+"");                drawBg(count);                drawminite(minutefloat);                mCanvas.save();                drawhour(hourfloat);                mCanvas.restore();            }        } catch (Exception e) {            e.printStackTrace();        } finally {            if (mCanvas != null)                mHolder.unlockCanvasAndPost(mCanvas);        }    }    private void drawminite(int angle) {        mCanvas.save();        //以中心坐标旋转画布画分钟手势图        mCanvas.rotate(angle, mCenter, getMeasuredHeight() / 2);        int imgsWidth = (int) (mRadius/3);        Rect rectm = new Rect(mCenter - imgsWidth / 2, getMeasuredHeight()/2  - mDimension, mCenter + imgsWidth / 2, getMeasuredHeight() / 2 );        mCanvas.drawBitmap(mImgsBitmap[1], null, rectm, null);        mCanvas.restore();    }    private void drawBg(int count) {        mCanvas.drawColor(Color.TRANSPARENT);        mCanvas.drawBitmap(mBgBitmap[count],null,new Rect(0,getMeasuredHeight()/2-getMeasuredWidth()/2,getMeasuredWidth(),getMeasuredHeight()/2+getMeasuredWidth()/2),null);    }    private void drawhour(int angle) {        mCanvas.rotate(angle,mCenter,getMeasuredHeight()/2);        //秒钟宽度        int imgsWidth = (int) (mRadius/3);        Rect recth = new Rect(mCenter - imgsWidth / 2, getMeasuredHeight()/2  - hDimension, mCenter + imgsWidth / 2, getMeasuredHeight()/2);        mCanvas.drawBitmap(mImgsBitmap[0], null, recth, null);    }}
源码下载地址:http://download.csdn.net/download/u012515603/9412799






0 0