日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > Android >内容正文

Android

Android 动态绘制曲线等各种图形

發(fā)布時(shí)間:2023/12/18 Android 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android 动态绘制曲线等各种图形 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Android 中動(dòng)態(tài)的繪制有兩種方法,一種是用OpenGL ES,它主要用來做3D圖形開發(fā),對(duì)于一般的應(yīng)用,我們會(huì)采取自定義一個(gè)View,然后覆蓋onDraw()的方法,下面說一下第二種方法。

基本的思路是:

1:創(chuàng)建一個(gè)類,繼承自View(或者SurfaceView)。

2:覆蓋onDraw()方法。

3:使用Canvas對(duì)象在界面上繪制不同的圖形,使用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è)非常簡(jiǎn)單的例子,下面是一個(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路徑的對(duì)象 private DrawPath dp;private int screenWidth, screenHeight;// 屏幕長(zhǎng)寬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)于清空畫布// 清空畫布,但是如果圖片有背景的話,則使用上面的重新初始化的方法,用該方法會(huì)將背景清空掉...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的集合里面取出最頂端對(duì)象, 畫在畫布上面即可。*/ 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();// 每一次記錄的路徑對(duì)象是不一樣的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 {

private TuyaView tuyaView = null;@Override public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);DisplayMetrics dm = new DisplayMetrics();getWindowManager().getDefaultDisplay().getMetrics(dm);tuyaView = new TuyaView(this, dm.widthPixels, dm.heightPixels);setContentView(tuyaView); }@Override public boolean onKeyDown(int keyCode, KeyEvent event) {if (keyCode == KeyEvent.KEYCODE_BACK) {// 返回鍵

// tuyaView.undo();
this.finish();
return true;
}
return super.onKeyDown(keyCode, event);
}

}

都是一些非常簡(jiǎn)單的例子,畫三角形,四邊形 等的原理都是一樣,希望對(duì)初學(xué)者有點(diǎn)作用。

原文:https://blog.csdn.net/dancing_with_wolf/article/details/24437043

總結(jié)

以上是生活随笔為你收集整理的Android 动态绘制曲线等各种图形的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。