1. 程式人生 > >Android自定義元件(四)

Android自定義元件(四)

1.陰影

陰影即可以為文字和圖形指定陰影,預設情況下,我們的文字和圖形都是繪製在主層(main layer)上,我們也可以將內容繪製到新的layer上,實際上陰影就是在main layer的下面添加了一個陰影層。

Paint類為此定義了一個名為setShadowLayer的方法:

public void setShadowLayer(float radius, float dx, float dy, int shadowColor),其中: radius:陰影半徑 dx: x 方向陰影的偏移量 dy: y 方向陰影的偏移量 shadowColor: 陰影的顏色

2.漸變

漸變就是繪圖的過程中顏色或者點陣圖以特定的規律進行變化。Graphics2D提供的漸變種類有:

 線性漸變: LinearGradient  徑向漸變: RadialGradient  掃描漸變: SweepGradient  點陣圖漸變: BitmapShader  混合漸變: ComposeShader

其中前三種漸變模式屬於顏色漸變,可以指定兩種或者兩種以上的顏色,根據顏色過渡演算法自動計算中間的過渡顏色。

而點陣圖漸變則不再是簡單的顏色漸變,而是以圖片作為貼片的有規律的變化。

混合漸變則是能將多種漸變進行組合,從而實現複雜的漸變效果。 

3.漸變類與Matrix

漸變類都繼承自同一個父類Shader,該類定義了一個public void setLocalMatrix(Matrix localM)的方法,該方法能與漸變結合,從而在填充漸變顏色的時候實現移位、旋轉、縮放和拉斜的效果。

    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setFocusable(true);
        setFocusableInTouchMode(true);
        float x = 160;
        float y = 100;
        mShader = new SweepGradient(x, y, new int[]{Color.GREEN,
                Color.BLACK,
                Color.GRAY,
                Color.GREEN}, null);
        mPaint.setShader(mShader);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Paint paint = mPaint;
        float x = 160;
        float y = 100;
        canvas.translate(300, 300);
        canvas.drawColor(Color.WHITE);
        mMatrix.setRotate(mRotate, x, y);
        mShader.setLocalMatrix(mMatrix);
        mRotate += 3;
        if (mRotate >= 360) {
            mRotate = 0;
        }
        invalidate();
        canvas.drawCircle(x, y, 380, paint);

    }

}

4.圖層 Canvas一般情況都會看做一個畫布,所有的繪圖操作都在這個畫布上繪製,但是對於複雜的繪圖操作,比如多層動畫、地圖等,需要Canvas提供的圖層的支援。這是,Canvas就需要建立一些中間層,按照“棧結構”來對其進行管理。

在我們進行繪製的時候,通常會建立新的圖層進行入棧,建立圖層的方法有:

public int saveLayer(float left, float top, float right, float bottom, Paint paint, int saveFlags) public int saveLayer(RectF bounds, Paint paint, int saveFlags) public int saveLayer(RectF bounds, Paint paint) public int saveLayer(float left, float top, float right, float bottom, Paint paint)

除了這些方法,還可以為圖層指定透明度:

public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags) public int saveLayerAlpha(RectF bounds, int alpha) public int saveLayerAlpha(float left, float top, float right, float bottom, int alpha, int saveFlags) public int saveLayerAlpha(float left, float top, float right, float bottom, int alpha)

 其中saveFlags用於指定儲存的標識位,上面的方法均會返回一個int型別的id作為layer出棧的標記。

出棧呼叫的方法為:public void restoreToCount(int saveCount)

5.點陣圖的運算技巧

 關於點陣圖的運算,一般可以簡化為以下幾個步驟:

1) 準備好分別代表 DST 和 SRC 的點陣圖, 同時準備第三個點陣圖, 該點陣圖用於繪製 DST 和 SRC 運算後的結果; 2) 建立大小合適的圖層(layer) 併入棧; 3) 先將 DST 點陣圖繪製在第三個點陣圖上; 4) 呼叫 Paint 的 setXfermode()方法定義點陣圖運算模式; 5) 再將 SRC 點陣圖繪製在第三個點陣圖上; 6) 清除點陣圖運算模式; 7) 圖層(layer) 出棧 8) 將第三個點陣圖繪製在 View 的 Canvas 上以便顯示。

public class MyView extends View {


    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Bitmap dst = Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888);
        Bitmap src = dst.copy(Bitmap.Config.ARGB_8888, true);
        Bitmap b3 = Bitmap.createBitmap(450, 450, Bitmap.Config.ARGB_8888);
        Canvas c1 = new Canvas(dst);
        Canvas c2 = new Canvas(src);
        Canvas c3 = new Canvas(b3);

        Paint p1 = new Paint();
        p1.setColor(Color.GRAY);
        c1.drawCircle(150, 150, 150, p1);
        Paint p2 = new Paint();
        p2.setColor(Color.GREEN);
        c2.drawRect(0, 0, 300, 300, p2);

//      定義畫筆
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
//      建立圖層
        int layer = c3.saveLayer(0, 0, 450, 450, null, Canvas.ALL_SAVE_FLAG);
//      畫圓
        c3.drawBitmap(dst, 0, 0, null);
//      定義點陣圖的運算模式
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DARKEN));
//      畫正方形
        c3.drawBitmap(src, 150, 150, paint);
//      清除運算效果
        paint.setXfermode(null);
//      恢復
        c3.restoreToCount(layer);
//      繪製到 Canvas 上
        canvas.drawBitmap(b3, 0, 0, null);