首页 > 代码库 > 4. 2D绘制与控件绘制

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     @Override142     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     @Override16     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         @Override55         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.HandClock12         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 = http://www.mamicode.com/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     @Override108     protected void onDetachedFromWindow() {109         super.onDetachedFromWindow();110         // 删除回调类111         handler.removeCallbacks(this);112     }113 114 }