Android 动态绘制曲线等各种图形
Android 中動(dòng)態(tài)的繪制有兩種方法,一種是用OpenGL ES,它主要用來做3D圖形開發(fā),對于一般的應(yīng)用,我們會采取自定義一個(gè)View,然后覆蓋onDraw()的方法,下面說一下第二種方法。
基本的思路是:
1:創(chuàng)建一個(gè)類,繼承自View(或者SurfaceView)。
2:覆蓋onDraw()方法。
3:使用Canvas對象在界面上繪制不同的圖形,使用invalidate()方法刷新界面
下面通過兩個(gè)例子來說明
一:彈球?qū)嵗?/p> 自定義一個(gè)View,代碼如下:
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.View;
public class MyView extends View implements Runnable{
//圖形當(dāng)前的坐標(biāo) private int mX = 20; private int mY = 20;public MyView(Context context,AttributeSet attrs){super(context,attrs);//獲取焦點(diǎn)setFocusable(true);//啟動(dòng)線程new Thread(this).start(); }@Override public void run() {RefreshThread mDrawHandler = new RefreshThread();while(!Thread.currentThread().isInterrupted()){Message msg = new Message();msg.what = 0x101;mDrawHandler.sendMessage(msg);try {Thread.sleep(500);} catch (Exception e) {e.printStackTrace();}} }@Override protected void onDraw(Canvas canvas) {//實(shí)例化畫筆Paint mPaint = new Paint();//設(shè)置畫筆顏色mPaint.setColor(Color.RED);//畫圓canvas.drawCircle(mX, mY, 20, mPaint);super.onDraw(canvas); }class RefreshThread extends Handler{@Overridepublic void handleMessage(Message msg) {if(msg.what==0x101){MyView.this.update();}super.handleMessage(msg);} }/*** 更新坐標(biāo)*/ private void update(){int height = getHeight();mY+=5;if(mY>=height){mY = 20;} }}
再創(chuàng)建一個(gè)Activity,在Activity中實(shí)例化這個(gè)自定義的View就行了,代碼如下:
import android.app.Activity;
import android.os.Bundle;
import com.example.views.MyView;
public class MyActivity extends Activity{
private MyView mView;@Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);mView = new MyView(this,null);setContentView(mView);}}
上面是一個(gè)非常簡單的例子,下面是一個(gè)比較復(fù)雜的,主要教大家通過觸屏,在界面上動(dòng)態(tài)的畫曲線,直接上代碼:
package com.example.views;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Bitmap.CompressFormat;
import android.os.Environment;
import android.view.MotionEvent;
import android.view.View;
/**
*
- @category: View實(shí)現(xiàn)涂鴉、撤銷以及重做功能
- @author: LuoYong
- @date: 2013-11-25
*/
public class TuyaView extends View {
private Bitmap mBitmap; private Canvas mCanvas; private Path mPath; private Paint mBitmapPaint;// 畫布的畫筆 private Paint mPaint;// 真實(shí)的畫筆 private float mX, mY;// 臨時(shí)點(diǎn)坐標(biāo) private static final float TOUCH_TOLERANCE = 4;// 保存Path路徑的集合,用List集合來模擬棧 private static List<DrawPath> savePath; // 記錄Path路徑的對象 private DrawPath dp;private int screenWidth, screenHeight;// 屏幕長寬private class DrawPath {public Path path;// 路徑public Paint paint;// 畫筆 }public TuyaView(Context context, int w, int h) {super(context);screenWidth = w;screenHeight = h;mBitmap = Bitmap.createBitmap(screenWidth, screenHeight,Bitmap.Config.ARGB_8888);// 保存一次一次繪制出來的圖形mCanvas = new Canvas(mBitmap);mBitmapPaint = new Paint(Paint.DITHER_FLAG);mPaint = new Paint();mPaint.setAntiAlias(true);mPaint.setStyle(Paint.Style.STROKE);mPaint.setStrokeJoin(Paint.Join.ROUND);// 設(shè)置外邊緣mPaint.setStrokeCap(Paint.Cap.SQUARE);// 形狀mPaint.setStrokeWidth(8);// 畫筆寬度mPaint.setColor(0xFF2145FF);// 畫筆顏色savePath = new ArrayList<DrawPath>(); }@Override public void onDraw(Canvas canvas) {canvas.drawColor(Color.TRANSPARENT);// 將前面已經(jīng)畫過得顯示出來canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);if (mPath != null) {// 實(shí)時(shí)的顯示canvas.drawPath(mPath, mPaint);} }private void touch_start(float x, float y) {mPath.moveTo(x, y);mX = x;mY = y; }private void touch_move(float x, float y) {float dx = Math.abs(x - mX);float dy = Math.abs(mY - y);if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {// 從x1,y1到x2,y2畫一條貝塞爾曲線,更平滑(直接用mPath.lineTo也是可以的)// 由此就可以制作各種畫筆mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);mX = x;mY = y;} }private void touch_up() {mPath.lineTo(mX, mY);mCanvas.drawPath(mPath, mPaint);// 將一條完整的路徑保存下來(相當(dāng)于入棧操作)savePath.add(dp);mPath = null;// 重新置空 }/*** 撤銷的核心思想就是將畫布清空, 將保存下來的Path路徑最后一個(gè)移除掉, 重新將路徑畫在畫布上面。*/ public void undo() {mBitmap = Bitmap.createBitmap(screenWidth, screenHeight,Bitmap.Config.ARGB_8888);mCanvas.setBitmap(mBitmap);// 重新設(shè)置畫布,相當(dāng)于清空畫布// 清空畫布,但是如果圖片有背景的話,則使用上面的重新初始化的方法,用該方法會將背景清空掉...if (savePath != null && savePath.size() > 0) {// 移除最后一個(gè)path,相當(dāng)于出棧操作savePath.remove(savePath.size() - 1);Iterator<DrawPath> iter = savePath.iterator();while (iter.hasNext()) {DrawPath drawPath = iter.next();mCanvas.drawPath(drawPath.path, drawPath.paint);}invalidate();// 刷新/* 在這里保存圖片純粹是為了方便,保存圖片進(jìn)行驗(yàn)證 */String fileUrl = Environment.getExternalStorageDirectory().toString() + "/android/data/test.png";try {FileOutputStream fos = new FileOutputStream(new File(fileUrl));mBitmap.compress(CompressFormat.PNG, 100, fos);fos.flush();fos.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}} }/*** 重做的核心思想就是將撤銷的路徑保存到另外一個(gè)集合里面(棧), 然后從redo的集合里面取出最頂端對象, 畫在畫布上面即可。*/ public void redo() {// TODO }@Override public boolean onTouchEvent(MotionEvent event) {float x = event.getX();float y = event.getY();switch (event.getAction()) {case MotionEvent.ACTION_DOWN:// 每次down下去重新new一個(gè)PathmPath = new Path();// 每一次記錄的路徑對象是不一樣的dp = new DrawPath();dp.path = mPath;dp.paint = mPaint;touch_start(x, y);invalidate();break;case MotionEvent.ACTION_MOVE:touch_move(x, y);invalidate();break;case MotionEvent.ACTION_UP:touch_up();invalidate();break;}return true; }}
Activity 類:
package com.example.activity;
import com.example.views.TuyaView;
import android.app.Activity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.KeyEvent;
/**
*
- @category: View實(shí)現(xiàn)涂鴉、撤銷以及重做功能
- @author LuoYong
- @date: 2013-11-25
*/
public class TuyaActivity extends Activity {
// tuyaView.undo();
this.finish();
return true;
}
return super.onKeyDown(keyCode, event);
}
}
都是一些非常簡單的例子,畫三角形,四邊形 等的原理都是一樣,希望對初學(xué)者有點(diǎn)作用。
原文:https://blog.csdn.net/dancing_with_wolf/article/details/24437043
總結(jié)
以上是生活随笔為你收集整理的Android 动态绘制曲线等各种图形的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: FFMpeg在Windows环境下的编译
- 下一篇: Android 曲线图绘制