Android中使用Canvas绘制简单的图形(二) 进阶 绘制钟表

来源:互联网 发布:初学者的编程软件mac 编辑:程序博客网 时间:2024/05/22 07:53

基础绘制 请阅读 http://blog.csdn.net/daweibalang717/article/details/51776446


通过上文可以学会简单的图形绘制,我们来进行一个钟表的绘制。


效果图:



布局文件:



<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context="com.example.myapplication.MainActivity">    <ImageView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:id="@+id/imageView"        android:layout_centerInParent="true"        android:layout_marginTop="55dp" /></RelativeLayout>

Java 文件:

 package com.example.myapplication;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Typeface;import android.os.AsyncTask;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.widget.ImageView;import java.util.Calendar;public class MainActivity extends AppCompatActivity {    private ImageView mClockImageView;    private int width = 600;    private int height = 600;    private Calendar mCanlendar;    //时分秒    private int mHours,mMinue,mSecond;    private boolean isRun;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mClockImageView = (ImageView) findViewById(R.id.imageView);        isRun = true;        MyClockTask task = new MyClockTask();        task.execute();    }    //AsyncTask 类 可参考博客:http://blog.csdn.net/Kaiwii/article/details/21541499    private class MyClockTask extends AsyncTask<Object,Bitmap,Object>{        @Override        protected Object doInBackground(Object[] objects) {            while (isRun){                //一秒钟重绘一次指针                publishProgress(getDrawClockPointer());                try {                    Thread.sleep(1000);                } catch (InterruptedException e) {                    e.printStackTrace();                }            }            return null;        }        @Override        protected void onProgressUpdate(Bitmap... values) {            super.onProgressUpdate(values);            //每次重绘的内容更新到 ImageView 上;            mClockImageView.setImageBitmap(values[0]);        }    }    //画指针    private Bitmap getDrawClockPointer(){        Bitmap bm = getDrawClockDial();        Canvas canvas = new Canvas(bm);        Paint paint = new Paint();        paint.setAntiAlias(true);        paint.setColor(Color.BLACK);        mCanlendar = Calendar.getInstance();        mHours = mCanlendar.get(Calendar.HOUR);        mMinue = mCanlendar.get(Calendar.MINUTE);        mSecond = mCanlendar.get(Calendar.SECOND);        canvas.save();        //画时针(参考表盘如何画数字的),一小时30度,再加上分钟的度数(60分钟,时针偏转30度),每分钟时针偏转 mMinue*(30.0f/60.0f),        float degreesH = mHours*30 + mMinue*(30.0f/60.0f);        //基于圆心旋转        canvas.rotate(degreesH,width / 2,height / 2);        //时针的风格        paint.setColor(Color.RED);        paint.setStrokeWidth(6);        //时针的长         float lengthH = (height/2)*0.4f;        //时针 : 第四个参数的解释:因为半径是 height/2 或 width/2,线是从圆心开始的,所以结束的Y坐标是:height - height/2 - length        canvas.drawLine(width / 2,height / 2,width / 2,height - height/2 - lengthH,paint);        canvas.restore();        canvas.save();        //画分针 每分钟 6度 在加上秒针的度数(60秒钟 偏转6度),那么每秒钟 分钟偏转的度数  mSecond*(6.0f/60.0f);        float degreesM = mMinue*6 + mSecond*(6.0f/60.0f);        //基于圆心旋转        canvas.rotate(degreesM,width / 2,height / 2);        //分针的风格        paint.setColor(Color.GREEN);        paint.setStrokeWidth(4);        //分针的长        float lengthM = (height/2)*0.6f;        //分针 : 第四个参数的解释:因为半径是 height/2 或 width/2,线是从圆心开始的,所以结束的Y坐标是:height - height/2 - length        canvas.drawLine(width / 2,height / 2,width / 2,height - height/2 - lengthM,paint);        canvas.restore();        canvas.save();        //画秒针 每秒 6度        float degreesS = mSecond*6;        //基于圆心旋转        canvas.rotate(degreesS,width / 2,height / 2);        //秒针的风格        paint.setColor(Color.BLUE);        paint.setStrokeWidth(2);        //秒针的长        float lengthS = (height/2)*0.8f;        //秒针 : 第四个参数的解释:因为半径是 height/2 或 width/2,线是从圆心开始的,所以结束的Y坐标是:height - height/2 - length        canvas.drawLine(width / 2,height / 2,width / 2,height - height/2 - lengthS,paint);        canvas.restore();        return bm;    }    //画表盘    private Bitmap getDrawClockDial() {        //创建Bitmap        Bitmap bm = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);        //创建画布        Canvas canvas = new Canvas(bm);        //创建画笔        Paint paint = new Paint();        //空心        paint.setStyle(Paint.Style.STROKE);        //颜色        paint.setColor(Color.BLACK);        //宽度        paint.setStrokeWidth(6);        //抗锯齿        paint.setAntiAlias(true);        //画一个圆,前两个参数是中心点,第三个是半径,第四个是画笔        //注:因为圆圈的宽度为20,所以我们在计算的时候要把宽度给算进来        canvas.drawCircle(width / 2, height / 2, (width - 6) / 2, paint);        //在圆的中间画一个点 (圆点)        paint.setStyle(Paint.Style.FILL);        canvas.drawCircle(width / 2, height / 2, 4, paint);        /**         * 方便理解:画布是个虚拟的感念,可理解为即坐标系,而我们要画的内容是画在bitmap上的。         *         * 现在要画刻度了,我们要怎么画呢,我们想象一个圈360度,总共12个小时         * 一个小时就是:360/12 = 30;         * 思路:我们先保存画布的状态 canvas.save();         * for循环中,我们把坐标系旋转30度,然后写上 1 ,         * 然后再30度,写上2 ...等旋转360度的时候写上 12         * 这时候画布正好转了一圈,但是,注意,注意:         * 我们调用了canvas.restore(); 就是把坐标系回到开始保存的状态,         * 开始的状态的意思是:(坐标系是 x 左到右横向,Y是从上到下),我们旋转了360度把数字都给写上了,         * 而且写完后 (坐标系是 x 左到右横向,Y是从上到下,因为我们旋转了360度),         * 但是我们毕竟旋转了360度。也就是说现在坐标系的状态         * 是360度,canvas.restore()就是把这状态转回0度,         * 当然了,你不调用canvas.save(); canvas.restore(); 也是可以的,毕竟是旋转了360度,我这里说这个其实         * 就是为了说明这两个方法。还有旋转的概念,旋转的其实是坐标系(之前我对这点特别迷惑,认为画的东西就在画布上)         * 参考博客:http://blog.csdn.net/dinko321/article/details/7679019         * */        //先保存现在画布的状态,打个比方说就是 现在记录现在画布的方向,那头朝上,那头朝下啊的什么的。        canvas.save();        //这个画笔用来画  3 、6、9、12 加粗        Paint textPaint = new Paint();        textPaint.setColor(Color.BLACK);        textPaint.setTextSize(25);        textPaint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));        textPaint.setTextAlign(Paint.Align.CENTER);        for (int i = 1; i <= 12; i++) {            //旋转30度 后两个参数是基于那个点旋转,这里是圆心            canvas.rotate(30, width / 2, height / 2);            // 3 、6、9、12 加粗            if (i % 3 == 0) {                //Y 值我是估计写的 关于这个函数可以看:http://blog.csdn.net/sirnuo/article/details/21165665                canvas.drawText(String.valueOf(i), width / 2, (20 + 6) * 2, textPaint);            } else {                paint.setTextSize(20);                paint.setTextAlign(Paint.Align.CENTER);                canvas.drawText(String.valueOf(i), width / 2, (20 + 6) * 2, paint);            }        }        canvas.restore();        return bm;    }    @Override    protected void onResume() {        super.onResume();        isRun = true;    }    @Override    protected void onPause() {        super.onPause();        isRun = false;    }    @Override    protected void onDestroy() {        super.onDestroy();    }}



本代码总结于学习视频,是用于备忘。函数参数说明都在代码注释中。



0 0
原创粉丝点击