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

自定义View实现米老鼠时钟

2016-01-21 12:49 495 查看
先看效果图,米老鼠的两个手分别指向时钟和分钟,然后米老鼠的脚在一秒执行一次动画操作。



分析完之后就先实现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 =
e699
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



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息