4. 2D绘制与控件绘制

绘制基本图形和文本

绘制图形和文本的基本方法

drawPoint(绘制点)、drawLine(绘制直线)、drawCircle(绘制圆) drawArc(绘制弧)、drawText(绘制文本) 

  1 package cn.eoe.draw;
  2 
  3 import android.app.Activity;
  4 import android.content.Context;
  5 import android.graphics.Canvas;
  6 import android.graphics.Color;
  7 import android.graphics.Paint;
  8 import android.graphics.RectF;
  9 import android.graphics.Paint.Style;
 10 import android.os.Bundle;
 11 import android.view.MotionEvent;
 12 import android.view.View;
 13 
 14 public class Main extends Activity {
 15     class MyView extends View {
 16         private Paint paint1 = new Paint();
 17         private Paint paint2 = new Paint();
 18         private Paint paint3 = new Paint();
 19         private boolean useCenter = true;
 20         private float[] textSizeArray = new float[] { 15, 18, 21, 24, 27 };
 21 
 22         @Override
 23         public boolean onTouchEvent(MotionEvent event) {
 24             if (useCenter) {
 25                 useCenter = false;
 26                 paint1.setColor(Color.RED);
 27                 paint2.setColor(Color.BLACK);
 28                 paint3.setColor(Color.GREEN);
 29 
 30                 paint1.setStrokeWidth(6);
 31                 paint2.setStrokeWidth(4);
 32                 paint3.setStrokeWidth(2);
 33 
 34             } else {
 35                 useCenter = true;
 36                 paint1.setColor(Color.BLACK);
 37                 paint2.setColor(Color.RED);
 38                 paint3.setColor(Color.BLUE);
 39                 paint1.setStrokeWidth(2);
 40                 paint2.setStrokeWidth(4);
 41                 paint3.setStrokeWidth(6);
 42             }
 43             for (int i = 0; i < textSizeArray.length / 2; i++) {
 44                 float textSize = textSizeArray[i];
 45 
 46                 textSizeArray[i] = textSizeArray[textSizeArray.length - i - 1];
 47                 textSizeArray[textSizeArray.length - i - 1] = textSize;
 48             }
 49 
 50             invalidate();
 51             return super.onTouchEvent(event);
 52         }
 53 
 54         public MyView(Context context) {
 55             super(context);
 56             setBackgroundColor(Color.WHITE);
 57 
 58             paint1.setColor(Color.BLACK);
 59             paint1.setStrokeWidth(2);
 60             paint2.setColor(Color.RED);
 61             paint2.setStrokeWidth(4);
 62             paint3.setColor(Color.BLUE);
 63             paint3.setStrokeWidth(6);
 64 
 65         }
 66 
 67         private void drawLinesExt(Canvas canvas, float[] pts, Paint paint) {
 68 
 69             float[] points = new float[pts.length * 2 - 4];
 70             for (int i = 0, j = 0; i < pts.length; i = i + 2) {
 71                 points[j++] = pts[i];
 72                 points[j++] = pts[i + 1];
 73 
 74                 if (i > 1 && i < pts.length - 2) {
 75                     points[j++] = pts[i];
 76                     points[j++] = pts[i + 1];
 77                 }
 78             }
 79 
 80             canvas.drawLines(points, paint);
 81         }
 82 
 83         @Override
 84         protected void onDraw(Canvas canvas) {
 85             canvas.drawPoint(60, 120, paint3);
 86             canvas.drawPoint(70, 130, paint3);
 87             canvas.drawPoints(new float[] { 70, 140, 75, 145, 75, 160 }, paint2);
 88             // canvas.drawPoints(new float[]
 89             // { 70, 140, 75, 145, 75, 160 }, 1,4,paint2);
 90 
 91             canvas.drawLine(10, 10, 300, 10, paint1);
 92             canvas.drawLine(10, 30, 300, 30, paint2);
 93             canvas.drawLine(10, 50, 300, 50, paint3);
 94             drawLinesExt(canvas, new float[] { 10, 70, 120, 70, 120, 170, 10,
 95                     170, 10, 70 }, paint2);
 96             drawLinesExt(canvas, new float[] { 25, 85, 105, 85, 105, 155, 25,
 97                     155, 25, 85 }, paint3);
 98             drawLinesExt(canvas, new float[] { 160, 70, 230, 150, 170, 155,
 99                     160, 70 }, paint2);
100             paint2.setStyle(Style.STROKE);
101             canvas.drawCircle(260, 110, 40, paint2);
102             paint2.setStyle(Style.FILL);
103             canvas.drawCircle(260, 110, 30, paint2);
104 
105             RectF rectF = new RectF();
106             rectF.left = 30;
107             rectF.top = 190;
108             rectF.right = 120;
109             rectF.bottom = 280;
110 
111             canvas.drawArc(rectF, 0, 200, useCenter, paint2);
112 
113             rectF.left = 140;
114             rectF.top = 190;
115             rectF.right = 280;
116             rectF.bottom = 290;
117             paint2.setStyle(Style.STROKE);
118             canvas.drawArc(rectF, 0, 360, useCenter, paint2);
119 
120             rectF.left = 160;
121             rectF.top = 190;
122             rectF.right = 260;
123             rectF.bottom = 290;
124             paint3.setStyle(Style.STROKE);
125             canvas.drawArc(rectF, 0, 360, useCenter, paint3);
126 
127             float y = 0;
128             for (int i = 0; i < textSizeArray.length; i++) {
129                 paint1.setTextSize(textSizeArray[i]);
130 
131                 paint1.setColor(Color.BLUE);
132                 canvas.drawText("Android(宽度:" + paint1.measureText("Android")
133                         + ")", 20, 315 + y, paint1);
134                 y += paint1.getTextSize() + 5;
135             }
136             paint1.setTextSize(22);
137 
138         }
139     }
140 
141     @Override
142     public void onCreate(Bundle savedInstanceState) {
143 
144         super.onCreate(savedInstanceState);
145         setContentView(new MyView(this));
146     }
147 }

 

绘制图像

绘制图形两种方法:

protected void onDraw(Canvas canvas){

     // 方法一

     canvas.drawBitmap(bitmap, 10, 10, null);

    // 方法二
    drawable.draw(canvas);

 

 1 package cn.eoe.draw.bitmap;
 2 
 3 import android.app.Activity;
 4 import android.content.Context;
 5 import android.graphics.Bitmap;
 6 import android.graphics.BitmapFactory;
 7 import android.graphics.Canvas;
 8 import android.graphics.Color;
 9 import android.graphics.drawable.Drawable;
10 import android.os.Bundle;
11 
12 import android.view.View;
13 
14 public class Main extends Activity {
15     @Override
16     protected void onCreate(Bundle savedInstanceState) {
17         super.onCreate(savedInstanceState);
18         setContentView(new MyView(this));
19     }
20 
21     private static class MyView extends View {
22         private Bitmap bitmap1;
23         private Bitmap bitmap2;
24         private Bitmap bitmap3;
25         private Bitmap bitmap4;
26         private Drawable drawable;
27 
28         public MyView(Context context) {
29             super(context);
30             setBackgroundColor(Color.WHITE);
31             java.io.InputStream is = context.getResources().openRawResource(
32                     R.drawable.panda);
33 
34             BitmapFactory.Options opts = new BitmapFactory.Options();
35             opts.inSampleSize = 2;
36             bitmap1 = BitmapFactory.decodeStream(is, null, opts);
37 
38             is = context.getResources().openRawResource(R.drawable.tiger);
39             bitmap2 = BitmapFactory.decodeStream(is);
40 
41             int w = bitmap2.getWidth();
42             int h = bitmap2.getHeight();
43             int[] pixels = new int[w * h];
44             bitmap2.getPixels(pixels, 0, w, 0, 0, w, h);
45             bitmap3 = Bitmap.createBitmap(pixels, 0, w, w, h,
46                     Bitmap.Config.ARGB_8888);
47             bitmap4 = Bitmap.createBitmap(pixels, 0, w, w, h,
48                     Bitmap.Config.ARGB_4444);
49 
50             drawable = context.getResources().getDrawable(R.drawable.button);
51             drawable.setBounds(50, 350, 180, 420);
52         }
53 
54         @Override
55         protected void onDraw(Canvas canvas) {
56 
57             canvas.drawBitmap(bitmap1, 10, 10, null);
58             canvas.drawBitmap(bitmap2, 10, 200, null);
59             canvas.drawBitmap(bitmap3, 110, 200, null);
60             canvas.drawBitmap(bitmap4, 210, 200, null);
61             drawable.draw(canvas);
62 
63         }
64     }
65 }

 

绘制指针时钟控件 

 

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:orientation="vertical" android:layout_width="fill_parent"
 4     android:layout_height="fill_parent" android:background="#FFF"
 5     android:gravity="center">
 6     <cn.eoe.handclock.widget.HandClock
 7         android:layout_width="wrap_content" android:layout_height="wrap_content"
 8         clockImageSrc="@drawable/clock1" scale="0.75" handCenterWidthScale="0.477"
 9         handCenterHeightScale="0.512" minuteHandSize="54" hourHandSize="40"/>
10 </LinearLayout>
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:orientation="vertical" android:layout_width="fill_parent"
 4     android:layout_height="fill_parent" android:background="#FFF"
 5     android:gravity="center_horizontal">
 6     <cn.eoe.handclock.widget.HandClock
 7         android:layout_width="wrap_content" android:layout_height="wrap_content"
 8         android:layout_marginTop="10dp" clockImageSrc="@drawable/clock2"
 9         scale="0.3" handCenterWidthScale="0.5" handCenterHeightScale="0.5"
10         minuteHandSize="154" hourHandSize="100" />
11     <cn.eoe.handclock.widget.HandClock
12         android:layout_width="wrap_content" android:layout_height="wrap_content"
13         android:layout_marginTop="10dp" clockImageSrc="@drawable/clock3"
14         scale="0.3" handCenterWidthScale="0.5" handCenterHeightScale="0.5"
15         minuteHandSize="154" hourHandSize="100" />
16 </LinearLayout>
17  
  1 package cn.eoe.handclock.widget;
  2 
  3 import java.util.Calendar;
  4 import android.content.Context;
  5 import android.graphics.Bitmap;
  6 import android.graphics.BitmapFactory;
  7 import android.graphics.Canvas;
  8 import android.graphics.Paint;
  9 import android.graphics.Rect;
 10 import android.os.Handler;
 11 import android.util.AttributeSet;
 12 import android.view.View;
 13 
 14 public class HandClock extends View implements Runnable {
 15     private int clockImageResourceId;
 16     private Bitmap bitmap;
 17     private float scale;
 18     private float handCenterWidthScale;
 19     private float handCenterHeightScale;
 20     private int minuteHandSize;
 21     private int hourHandSize;
 22     private Handler handler = new Handler();
 23 
 24     @Override
 25     public void run() {
 26         // 重新绘制View
 27         invalidate();
 28         // 重新设置定时器,在60秒后调用run方法
 29         handler.postDelayed(this, 60 * 1000);
 30     }
 31 
 32     @Override
 33     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 34         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
 35         // 根据图像的实际大小等比例设置View的大小
 36         setMeasuredDimension((int) (bitmap.getWidth() * scale),
 37                 (int) (bitmap.getHeight() * scale));
 38     }
 39 
 40     @Override
 41     protected void onDraw(Canvas canvas) {
 42         super.onDraw(canvas);
 43         Paint paint = new Paint();
 44         Rect src = new Rect();
 45         Rect target = new Rect();
 46         src.left = 0;
 47         src.top = 0;
 48         src.right = bitmap.getWidth();
 49         src.bottom = bitmap.getHeight();
 50 
 51         target.left = 0;
 52         target.top = 0;
 53         target.bottom = (int) (src.bottom * scale);
 54         target.right = (int) (src.right * scale);
 55         // 画表盘图像
 56         canvas.drawBitmap(bitmap, src, target, paint);
 57         // 计算表盘中心点的横纵坐标
 58         float centerX = bitmap.getWidth() * scale * handCenterWidthScale;
 59         float centerY = bitmap.getHeight() * scale * handCenterHeightScale;
 60         // 表表盘中心点画一个半径为5的实心圆圈
 61         canvas.drawCircle(centerX, centerY, 5, paint);
 62         // 设置分针为3个象素粗
 63         paint.setStrokeWidth(3);
 64         Calendar calendar = Calendar.getInstance();
 65         int currentMinute = calendar.get(Calendar.MINUTE);
 66         int currentHour = calendar.get(Calendar.HOUR);
 67         // 计算分针和时间的弧度
 68         double minuteRadian = Math
 69                 .toRadians((360 - ((currentMinute * 6) - 90)) % 360);
 70         double hourRadian = Math.toRadians((360 - ((currentHour * 30) - 90))
 71                 % 360 - (30 * currentMinute / 60));
 72         // 在表盘上画分针
 73         canvas.drawLine(centerX, centerY, (int) (centerX + minuteHandSize
 74                 * Math.cos(minuteRadian)), (int) (centerY - minuteHandSize
 75                 * Math.sin(minuteRadian)), paint);
 76         // 设置实针为4个象素粗
 77         paint.setStrokeWidth(4);
 78         // 在表盘上画时针
 79         canvas.drawLine(centerX, centerY,
 80                 (int) (centerX + hourHandSize * Math.cos(hourRadian)),
 81                 (int) (centerY - hourHandSize * Math.sin(hourRadian)), paint);
 82     }
 83 
 84     public HandClock(Context context, AttributeSet attrs) {
 85         super(context, attrs);
 86         // 读取相应的属性值
 87         clockImageResourceId = attrs.getAttributeResourceValue(null,
 88                 "clockImageSrc", 0);
 89         if (clockImageResourceId > 0)
 90             bitmap = BitmapFactory.decodeResource(getResources(),
 91                     clockImageResourceId);
 92         scale = attrs.getAttributeFloatValue(null, "scale", 1);
 93         handCenterWidthScale = attrs.getAttributeFloatValue(null,
 94                 "handCenterWidthScale", bitmap.getWidth() / 2);
 95         handCenterHeightScale = attrs.getAttributeFloatValue(null,
 96                 "handCenterHeightScale", bitmap.getHeight() / 2);
 97         // 在读取分针和时针长度后,将其值按图像的缩放比例进行缩放
 98         minuteHandSize = (int) (attrs.getAttributeIntValue(null,
 99                 "minuteHandSize", 0) * scale);
100         hourHandSize = (int) (attrs.getAttributeIntValue(null, "hourHandSize",
101                 0) * scale);
102         int currentSecond = Calendar.getInstance().get(Calendar.SECOND);
103         // 将定时器设在0分时执行run方法
104         handler.postDelayed(this, (60 - currentSecond) * 1000);
105     }
106 
107     @Override
108     protected void onDetachedFromWindow() {
109         super.onDetachedFromWindow();
110         // 删除回调类
111         handler.removeCallbacks(this);
112     }
113 
114 }

 

 

 

 

posted on 2014-07-27 16:02  大米稀饭  阅读(383)  评论(0编辑  收藏  举报