Android之繪圖

來源:互聯網
上載者:User

標籤:

一直對畫畫相關不感冒,但是Android的繪圖機制還是要硬著頭皮學

繪畫主要是使用paint(畫筆)在canvas(畫布)進行各種圖形的繪製,畫矩形、圓、三角形等點線構成的2維圖形

//矩形  drawRect (float left, float top, float right, float bottom, Paint paint)        canvas.drawRect(50, 100, 200, 200, paint);        //圓  drawCircle (float cx, float cy, float radius, Paint paint)        canvas.drawCircle(width / 2, height / 2, 100, paint);        //三角形(畫線)        //執行個體化路徑        Path path = new Path();        path.moveTo(80, 300);// 此點為多邊形的起點        path.lineTo(120, 250);        path.lineTo(80, 250);        path.close(); // 使這些點構成封閉的多邊形        canvas.drawPath(path, paint);        //扇形 RectF (float left, float top, float right, float bottom)        RectF rectF = new RectF(160, 200, 400, 400);        // drawArc (RectF oval, float startAngle 起始弧度, float sweepAngle 掃過的弧度, boolean useCenter, Paint paint)        canvas.drawArc(rectF, 200, 130, true, paint);        //橢圓        rectF = new RectF(300, 300, 600, 600);        //  set (float left, float top, float right, float bottom)        rectF.set(210,100,450,200);        // drawOval (RectF oval, Paint paint)        canvas.drawOval(rectF, paint);        //曲線        //設定空心        paint.setStyle(Paint.Style.STROKE);        path = new Path();        path.moveTo(500, 500);//設定Path的起點        path.quadTo(550, 510, 670, 600);  //設定路徑點和終點        canvas.drawPath(path, paint);        //文字+ 圖片        paint.setTextSize(30);        //文本 drawText (String text, float x, float y, Paint paint)        canvas.drawText("slack", 350, 330, paint);        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);        //圖片 drawBitmap (Bitmap bitmap, float left, float top, Paint paint)        canvas.drawBitmap(bitmap, 320, 360, paint);
canvas有幾個重要的方法,畫圖時會使用到,類似ps裡的圖層,旋轉,位移的概念
/*     *  Canvas.save() 將之前的映像儲存起來,讓後續的操作能像在新的畫布一樣操作    *  Canvas.restore() 合并圖層    *  Canvas.translate() 平移 我們繪製的時候預設座標點事左上方的起始點,那麼我們調用translate(x,y)之後,    則將原點(0,0)移動到(x,y)之後的所有繪圖都是在這一點上執行的    *  Canvas.roate() 旋轉    * */
畫一個時鐘,就把這些理解了

//畫時鐘        // 畫外圓        Paint paintCircle = new Paint();        paintCircle.setAntiAlias(true);        paintCircle.setStyle(Paint.Style.STROKE);        paintCircle.setStrokeWidth(5);        canvas.drawCircle(width / 2, height / 2, width / 3, paintCircle);        // 畫刻度        Paint paintDegree = new Paint();        paintDegree.setStrokeWidth(3);        canvas.rotate(30, width / 2, height / 2);        for (int i = 1; i <= 12; i++) {            // 區別整點和非整點            if (i == 3 || i == 6 || i == 9 || i == 12 ) {                paintDegree.setStrokeWidth(5);                paintDegree.setTextSize(30);                // drawLine (float startX, float startY, float stopX, float stopY, Paint paint)                canvas.drawLine(width / 2, height / 2 - width / 3,                        width / 2, height / 2 - width / 3 + 60, paintDegree);                String degree = String.valueOf(i);                canvas.drawText(degree,                        width / 2 - paintDegree.measureText(degree) / 3,                        height / 2 - width / 3 + 90, paintDegree);            } else {                paintDegree.setStrokeWidth(3);                paintDegree.setTextSize(15);                // 圓上的一點(x = 螢幕寬一半, y = 螢幕的一半 - 半徑)                canvas.drawLine(width / 2, height / 2 - width / 3,                        width / 2, height / 2 - width / 3 + 30, paintDegree);                String degree = String.valueOf(i);                canvas.drawText(degree,                        width / 2 - paintDegree.measureText(degree) / 3,                        height / 2 - width / 3 + 60, paintDegree);            }            // 通過旋轉畫布——實際上是旋轉了畫圖的座標軸 簡化座標運算            canvas.rotate(30, width / 2, height / 2);        }        canvas.save();        // 畫指標        Paint paintHour = new Paint();        paintHour.setStrokeWidth(15);        Paint paintMinute = new Paint();        paintMinute.setStrokeWidth(10);        //繪製的時候預設座標點事左上方的起始點,那麼我們調用translate(x,y)之後,則將原點(0,0)移動到(x,y)之後的所有繪圖都是在這一點上執行的        canvas.translate(width / 2, height / 2);        canvas.drawPoint(0, 0, paintHour);//圓點        canvas.drawLine(0, 0, 100, 100, paintHour);        canvas.drawLine(0, 0, 100, -200, paintMinute);        canvas.restore();
類比刮刮樂


// PorterDuffXfermode 刮刮樂 通過DST_IN.SRC_IN模式來實現將一個矩形變成圓角圖片的效果        mPaint = new Paint();        mPaint.setAlpha(0);        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));        mPaint.setStyle(Paint.Style.STROKE);        mPaint.setStrokeJoin(Paint.Join.ROUND);        mPaint.setStrokeWidth(50);        mPaint.setStrokeCap(Paint.Cap.ROUND);        mPath = new Path();        // createBitmap (int width, int height, Bitmap.Config config)        mFgBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);        mCanvas = new Canvas(mFgBitmap);        mCanvas.drawColor(Color.GRAY);
/**     * 觸摸事件     * 畫一條透明的線  曲線     * @param event     * @return     */    @Override    public boolean onTouchEvent(MotionEvent event) {        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                mPath.reset();                lastX = event.getX();                lastY = event.getY();                mPath.moveTo(lastX, lastY);//起點                break;            case MotionEvent.ACTION_UP:                mPath.lineTo(event.getX(), event.getY());                break;            case MotionEvent.ACTION_MOVE:                //移動時,記錄這一次的點位置                mPath.quadTo(lastX, lastY, event.getX(), event.getY());  //設定曲線路徑點和終點                lastX = event.getX();                lastY = event.getY();                break;        }        mCanvas.drawPath(mPath, mPaint);        invalidate();        return true;    }

@Override    public void draw(Canvas canvas) {        super.draw(canvas);        //刮刮樂        canvas.drawBitmap(mFgBitmap, 0, 0, null);    }


SurfaceView主要用於頻繁重新整理處,做一個畫板


SurfaceView的簡單使用也簡單

public class SurfaView extends SurfaceView implements SurfaceHolder.Callback, Runnable 
線上程裡處理繪畫的事件,貼上代碼

import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Path;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.SurfaceHolder;import android.view.SurfaceView;/** * SurfaceView的使用 * Created by chenling on 2016/5/9. * 1.View主要用於自動更新的情況下,而surfaceVicw主要適用於被動更新,例如頻繁重新整理 * 2.View在主線程中重新整理,而surfaceView通常會通過一 個子線程來進行頁面重新整理。 * 3.View在繪製的時候沒有雙緩衝機制,而surfaceVicw在底層實現機制中就已經實現了雙緩衝機制; */public class SurfaView extends SurfaceView implements SurfaceHolder.Callback, Runnable {    //SurfaceHolder    private SurfaceHolder mHolder;    //用於繪製的Canvas    private Canvas mCanvas;    //子線程標誌位    private boolean mIsDrawing;    private float lastX,lastY;    private Path mPath;    private Paint mPaint;    /**     * 構造方法     *     * @param context     * @param attrs     */    public SurfaView(Context context, AttributeSet attrs) {        super(context, attrs);        mPath = new Path();        mPaint = new Paint();        mPaint.setStrokeWidth(20);        mPaint.setAntiAlias(true);        mPaint.setStyle(Paint.Style.STROKE);        mHolder = getHolder();        mHolder.addCallback(this);        setFocusable(true);        setFocusableInTouchMode(true);        setKeepScreenOn(true);    }    // 建立    @Override    public void surfaceCreated(SurfaceHolder holder) {        mIsDrawing = true;        new Thread(this).start();    }    // 改變    @Override    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {    }    //銷毀    @Override    public void surfaceDestroyed(SurfaceHolder holder) {        mIsDrawing = false;    }    @Override    public void run() {        while (mIsDrawing) {            draw();//            lastX += 1;//            lastY = (int) (100 * Math.sin(lastX * 2 * Math.PI / 180) + 400);//            mPath.lineTo(lastX, lastY);        }    }    // 負責繪畫,頻繁重新整理    private void draw() {        try {            mCanvas = mHolder.lockCanvas();            mCanvas.drawColor(Color.WHITE);            mCanvas.drawPath(mPath, mPaint);        } catch (Exception e) {        } finally {            if (mCanvas != null) {                //提交                mHolder.unlockCanvasAndPost(mCanvas);            }        }    }    /**     * 觸摸事件     *     * @param event     * @return     */    @Override    public boolean onTouchEvent(MotionEvent event) {        lastX =  event.getX();        lastY =  event.getY();        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                mPath.moveTo(lastX, lastY);                break;            case MotionEvent.ACTION_MOVE:                mPath.lineTo(lastX,lastY);                break;            case MotionEvent.ACTION_UP:                break;        }        return true;    }}


附件:源碼:https://github.com/CL-window/android_paint


Android之繪圖

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.