自定義發票

先貼圖:

這個圖就是發票的原形了,裏面關鍵部分就是:

//用來保存Canvas的狀態。save之後,可以調用Canvas的平移、放縮、旋轉、錯切、裁剪等操作
canvas.save();
//Canvas的平移
canvas.translate(x,y)
//用來恢復Canvas之前保存的狀態。防止save後對Canvas執行的操作對後續的繪製有影響
canvas.restore();

注意:save和restore要配對使用(restore可以比save少,但不能多),如果restore調用次數比save多,會引發Error。

代碼:

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

/**
 * 自定義發票
 */
public class InvoiceView extends View{
    private Paint paint;
    /**畫布寬 */
    private int width;
    /**畫布高*/
    private int height;
    /**圓半徑*/
    private int radius=10;
    /**圓齒輪個數*/
    private int gearcount;
    /** 當距離不足與在繪製一個圓的時候兩邊的空隙*/
    private int marginleft_right;
    private RectF rectF;

    public InvoiceView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    public InvoiceView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public InvoiceView(Context context) {
        super(context);
        init();
    }

    private void init() {
        paint=new Paint();
        // 抗鋸齒
        paint.setAntiAlias(true);
        // 位圖濾波
        paint.setFilterBitmap(true);
        // 防抖動
        paint.setDither(true);
        paint.setStyle(Style.STROKE);
        paint.setColor(Color.GREEN);
    }
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        width=measure(widthMeasureSpec,true);
        height=measure(heightMeasureSpec,false);
        setMeasuredDimension(width, height);
    }
    /**
     * 測量
     * @param measureSpec
     * @param b
     * @return
     */
    private int measure(int measureSpec, boolean b) {
        int result=0;
        int size=MeasureSpec.getSize(measureSpec);
        int mode=MeasureSpec.getMode(measureSpec);
        if(mode==MeasureSpec.AT_MOST){ //精準
            result=size;
        }else{
            result=Math.max(size,result);
        }
        return result;
    }
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        width=w;
        height=h;
    }
    @Override
    protected void onDraw(Canvas canvas) {
        drawGear(canvas);
    }
    /**
     * 繪製發票輪廓
     * @param canvas
     */
    private void drawGear(Canvas canvas) {
        measureGearcount();
        canvas.save();
        canvas.drawLine(0, 0, 0, height, paint);
        if(marginleft_right!=0)
            canvas.drawLine(0, height, marginleft_right,height, paint);
        rectF=new RectF(0,height-radius*2,radius*2, height+radius*2);
        canvas.translate(marginleft_right, 0); 
        for(int a=0;a<gearcount;a++){
            canvas.drawArc(rectF, 180, 180, false, paint);
            canvas.translate(radius*2, 0); //移動的是座標系 並不是畫布
        }
        canvas.restore();
        if(marginleft_right!=0)
            canvas.drawLine(width-marginleft_right, height, width, height, paint);
        canvas.drawLine(width, height, width, 0, paint);
        canvas.drawLine(width, 0, 0, 0, paint);
        //畫圖片(正常情況下,一般是畫二維碼)
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);  
        canvas.drawBitmap(bitmap,width/2-bitmap.getWidth()/2,height/2-bitmap.getHeight()/2, paint);  
    }
    /**
     * 計算圓齒輪個數 及空隙
     */
    private void measureGearcount() {
        int a=width%(radius*2);
        gearcount=width/(radius*2);
        //不等於0表示可以繪製gearcount+1/n個圓
        if(a!=0){
            marginleft_right=(width-gearcount*radius*2)/2;
        }
    }

}
發佈了75 篇原創文章 · 獲贊 38 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章