Android0917(自定義的View、繪製簡單圖形、Bitmap)(二)

繪製簡單圖形

下面是Canvas類常用的方法:

drawRect(RectF rect, Paint paint) //繪製區域,參數一爲RectF一個區域

drawPath(Path path, Paint paint) //繪製一個路徑,參數一爲Path路徑對象

drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) //貼圖,參數一就是我們常規的Bitmap對象,參數二是源區域(這裏是bitmap),參數三是目標區域(應該在canvas的位置和大小),參數四是Paint畫刷對象,因爲用到了縮放和拉伸的可能,當原始Rect不等於目標Rect時性能將會有大幅損失。

drawLine(float startX, float startY, float stopX, float stopY, Paintpaint) //畫線,參數一起始點的x軸位置,參數二起始點的y軸位置,參數三終點的x軸水平位置,參數四y軸垂直位置,最後一個參數爲Paint 畫刷對象。

drawPoint(float x, float y, Paint paint) //畫點,參數一水平x軸,參數二垂直y軸,第三個參數爲Paint對象。

drawText(String text, float x, floaty, Paint paint) //渲染文本,Canvas類除了上面的還可以描繪文字,參數一是String類型的文本,參數二x軸,參數三y軸,參數四是Paint對象。

drawOval(RectF oval, Paint paint)//畫橢圓,參數一是掃描區域,參數二爲paint對象;
drawCircle(float cx, float cy, float radius,Paint paint)// 繪製圓,參數一是中心點的x軸,參數二是中心點的y軸,參數三是半徑,參數四是paint對象;

drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)//畫弧,

參數一是RectF對象,一個矩形區域橢圓形的界限用於定義在形狀、大小、電弧,參數二是起始角(度)在電弧的開始,

參數三掃描角(度)開始順時針測量的,參數四是如果這是真的話,包括橢圓中心的電弧,並關閉它,如果它是假這將是一個弧線,參數五是Paint對象;

還要理解一個paint類:
Paint 代表了Canvas上的畫筆、畫刷、顏料等等;

Paint類常用方法:

setARGB(int a, int r, int g, int b) // 設置 Paint對象顏色,參數一爲alpha透明值

setAlpha(int a) // 設置alpha不透明度,範圍爲0~255

setAntiAlias(boolean aa) // 是否抗鋸齒

setColor(int color) // 設置顏色,這裏Android內部定義的有Color類包含了一些常見顏色定義

setTextScaleX(float scaleX) // 設置文本縮放倍數,1.0f爲原始

setTextSize(float textSize) // 設置字體大小

setUnderlineText(booleanunderlineText) // 設置下劃線

MyPath.java

public class MyPath extends View{
    private int width;
    private int height;
    private Paint mPaint;
    private Paint mPaintText;
    private Path mPath;
    private Path mPathCircle;
    private Path mPathLine;
    private Paint mPaintLine;
    private Path mPathWave;
    private Paint mPaintWave;
    private static final int WAVE_LINE=0x23;
    private int count=0;
    private Bitmap mBitmap;
    private Handler handler=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch(msg.what){
                case WAVE_LINE:
                    count+=10;
                    if (count>160) {
                        count = 0;
                    }
                    invalidate();// 刷新
                    handler.sendEmptyMessageDelayed(WAVE_LINE,100);
                    break;
            }
        }
    };
    public MyPath(Context context) {
        super(context);
    }

    public MyPath(Context context, AttributeSet attrs) {
        super(context, attrs);
        //設置繪製文字的畫筆
        mPaintText=new Paint();
        mPaintText.setColor(Color.BLUE);
        mPaintText.setTextSize(50);//設置畫筆大小
        mPaintText.setStyle(Paint.Style.STROKE);//消除鋸齒
        //設置繪製畫筆的屬性
        mPaint=new Paint();
        mPaint.setColor(Color.GREEN);
        mPaint.setStrokeWidth(10);//設置畫筆寬度
        mPaint.setStyle(Paint.Style.STROKE);
        //設置繪畫線段的畫筆
        mPaintLine=new Paint();
        mPaintLine.setColor(Color.RED);
        mPaintLine.setStyle(Paint.Style.STROKE);
        mPaintLine.setStrokeWidth(10);
        //設置繪畫波浪線的畫筆屬性
        mPaintWave=new Paint();
        mPaintWave.setColor(Color.YELLOW);
        mPaintWave.setStrokeWidth(10);
        mPaintWave.setStyle(Paint.Style.STROKE);
        //設置路徑
        mPathWave=new Path();//設置波浪線的路徑
        mPath=new Path();//設置路徑
        mPathCircle=new Path();//設置圓形的路徑
        mPathLine=new Path();//設置線段的路徑

        handler.sendEmptyMessageDelayed(WAVE_LINE, 100);
        //設置初始化位圖Bitmap,
        mBitmap= BitmapFactory.decodeResource(getResources(), R.mipmap.zun);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width=getDefaultSize(getSuggestedMinimumWidth(),widthMeasureSpec);
        height=getDefaultSize(getSuggestedMinimumHeight(),heightMeasureSpec);
        setMeasuredDimension(width,height);//設置畫布的大小,長和寬
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPath.moveTo(100, 100);//設置路徑的第一個點座標
        mPath.lineTo(150,150);//設置下一個點的座標
        mPath.lineTo(100,150);//設置下一個點的座標
        mPath.close();//封閉路徑
        canvas.drawBitmap(mBitmap,width/2,height/2,mPaint);
        //設置圓形路徑,Path.Direction設置轉動方向,CW是順時針,CCW是逆時針
        mPathCircle.addCircle(width/2,height/2,width/4,Path.Direction.CW);
        // canvas.drawPath繪製特定的路徑,第一個參數傳具體的路徑Path實例對象,第二參數傳畫筆
        canvas.drawPath(mPath,mPaint);//設置路徑
        canvas.drawPath(mPathCircle,mPaint);
        //canvas.drawTextOnPath設置文字沿路徑排列,第一個參數是文字內容,第二個參數是沿的路徑Path實例對象
        //第三個參數和第四個參數是橫縱偏移量,最後一個是畫筆
        canvas.drawTextOnPath("我是沿着路徑走的一行字",mPathCircle,10,50,mPaintText);
        //Path.quadTo用來繪製貝賽爾曲線,前兩個參數是控制點的橫縱座標,後兩個參數是後一個點的橫縱座標
        mPathLine.moveTo(width/8*3,height/8*3);
        mPathLine.quadTo(width/2,height/2+width/4,width/8*5,height/8*3);
        canvas.drawPath(mPathLine,mPaintLine);

        mPathWave.reset();
        mPathWave.moveTo(count,height/2+width/16);
        //Path.rQuadTo()方法繪製曲線時,會把上一點的座標當做是原點座標,依次往後
        for (int i=0;i<10;i++){
            mPathWave.rQuadTo(40,30,80,0);
            mPathWave.rQuadTo(40,-30,80,0);
        }
        canvas.drawPath(mPathWave,mPaintWave);
    }
}

activity_path.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
  android:background="@mipmap/imagebac">
<com.example.administrator.canvas.widget.MyPath
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
</LinearLayout>

MyPathActivity.java

public class MyPathActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_path);
    }
}

這裏寫圖片描述

Bitmap、Matrix

位於android.graphics.Matrix包下的Matrix是擁有3 x3的座標變換矩陣的矩陣類。用於對位圖進行一些變化

1、Translate—平移變換

 matrix.postTranslate(0,mBitmapHeigtht*2);//沿y軸向下平移Bitmap高的2倍

2、Scale—縮放變換

matrix.postScale(2,2);//放大2倍

3、Rotate—旋轉變換

 matrix.postRotate(180);//旋轉180度

4、Skew—錯切變換

 matrix.postSkew(1,0);//x軸上的值不變,拉伸y軸上的值

5、Values—-對稱

 float matrix_values[]={1f,0f,0f,0f,-1f,0f,0f,0f,1f};//關於x軸對稱,倒影效果
matrix.setValues(matrix_values);
float matrix_values2[]={-1f,0f,0f,0f,1f,0f,0f,0f,1f};//關於y軸對稱,鏡面效果
matrix.setValues(matrix_values2);

Bitmap實現在android.graphics包中。Bitmap類的構造函數是私有的,外面並不能實例化.BitmapFactory類提供了創建Bitmap的接口,而JNI接口來實例化Bitmap的.如下:

 mBitmap= BitmapFactory.decodeResource(getResources(), R.mipmap.betterfly);//decodeResource能夠從給定的資源中解析出新的位圖,第一個參數是包含圖像數據的資源對象,第二個參數是圖像數據的資源標識

得到位圖Bitmap的寬和高

mBitmapWidth=mBitmap.getWidth();//得到位圖的寬
mBitmapHeigtht =mBitmap.getHeight();//得到位圖的高

將位圖繪製到畫布上,canvas.drawBitmap()方法,第一個參數是位圖實例對象Bitmap,第二個和第三個參數是位圖得左上角位於畫布中的位置,最後一個是畫筆

canvas.drawBitmap(mBitmap,0,0,mPaint);

MyBitmap.java

public class MyBitmap extends View {
    private int width;
    private int height;
    private Paint mPaint;
    private Bitmap mBitmap;
    private Matrix matrix;
    private int mBitmapWidth;
    private int mBitmapHeigtht;
    public MyBitmap(Context context) {
        super(context);
    }

    public MyBitmap(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPaint=new Paint();
        mPaint.setColor(Color.GREEN);
        mPaint.setStrokeWidth(10);
        mPaint.setStyle(Paint.Style.STROKE);
        mBitmap= BitmapFactory.decodeResource(getResources(), R.mipmap.betterfly);
        matrix=new Matrix();
        mBitmapWidth=mBitmap.getWidth();
        mBitmapHeigtht =mBitmap.getHeight();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width=getDefaultSize(getSuggestedMinimumWidth(),widthMeasureSpec);
        height=getDefaultSize(getSuggestedMinimumHeight(),heightMeasureSpec);
        setMeasuredDimension(width,height);//設置畫布的大小,長和寬
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawBitmap(mBitmap,0,0,mPaint);

        matrix.reset();
        matrix.postScale(2,2);//放大2倍
        canvas.drawBitmap(mBitmap,matrix,mPaint);

        matrix.reset();;
        canvas.drawBitmap(mBitmap,matrix,mPaint);
        matrix.postTranslate(0,mBitmapHeigtht*2);//平移
        canvas.drawBitmap(mBitmap,matrix,mPaint);

        matrix.reset();
        matrix.postRotate(180);//旋轉
        matrix.postTranslate(mBitmapWidth*2,mBitmapHeigtht*3);
        canvas.drawBitmap(mBitmap,matrix,mPaint);

        matrix.reset();
        float matrix_values[]={1f,0f,0f,0f,-1f,0f,0f,0f,1f};//關於x軸對稱,倒影效果
        matrix.setValues(matrix_values);
        matrix.postTranslate(0,mBitmapHeigtht*2);
        canvas.drawBitmap(mBitmap,matrix,mPaint);

        matrix.reset();;
        float matrix_values2[]={-1f,0f,0f,0f,1f,0f,0f,0f,1f};//關於y軸對稱,鏡面效果
        matrix.setValues(matrix_values2);
        matrix.postTranslate(mBitmapWidth*2,0);
        canvas.drawBitmap(mBitmap,matrix,mPaint);

        matrix.reset();
        matrix.postSkew(1,0);//拉伸
        matrix.postTranslate(0,mBitmapHeigtht*3);
        canvas.drawBitmap(mBitmap,matrix,mPaint);
    }
}

activity_bitmap.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
<com.example.administrator.canvas.widget.MyBitmap
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
</LinearLayout>

MyBitmapActivity.java

public class MyBitmapActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bitmap);
    }
}

這裏寫圖片描述

位圖相交

這裏寫圖片描述

MyBitmapView.java

public class MyBitmapView extends View {
    private int width;
    private int height;
    private Paint mPaintCircle;
    private Paint mPaintRect;
    private Bitmap mBitmap;
    private Canvas canvasBit;
    public MyBitmapView(Context context) {
        super(context);
    }

    public MyBitmapView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPaintCircle=new Paint();
        mPaintCircle.setColor(Color.YELLOW);

        mPaintRect=new Paint();
        mPaintRect.setColor(Color.GREEN);
    //PorterDuffXfermode(PorterDuff.Mode.XOR)創建一個xfermode使用指定的波特達夫模式。參數爲運用波特達夫模式
        PorterDuffXfermode modeXOR=new PorterDuffXfermode(PorterDuff.Mode.XOR);
        //setXfermode()方法設置或清除xfermode對象。參數爲xfermode的實例對象
     mPaintRect.setXfermode(modeXOR);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width=getDefaultSize(getSuggestedMinimumWidth(),widthMeasureSpec);
        height=getDefaultSize(getSuggestedMinimumHeight(),heightMeasureSpec);
        setMeasuredDimension(width,height);//設置畫布的大小,長和寬
//Bitmap.createBitmap()返回與指定的寬度和高度可變的位圖。 
//Bitmap.Config描述了一個位圖結構如何存儲像素       mBitmap=Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888);
        //Canvas(mBitmap)方法用指定的位圖構造一個畫布來繪製。
        canvasBit=new Canvas(mBitmap);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        canvasBit.drawCircle(width/4,height/4,width/4,mPaintCircle);
        canvasBit.drawRect(0,0,width/4,width/4,mPaintRect);
        canvas.drawBitmap(mBitmap,0,0,null);
    }
}

activity_bitmapview.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
<com.example.administrator.canvas.widget.MyBitmapView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
</LinearLayout>

MyBitmapView.java

public class MyBitmapViewActivity extends Activity{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bitmapview);
    }
}

這裏寫圖片描述

MySilder.java

public class MySilder extends View {
    private int width;
    private int height;
    private Paint mPaint;
    private Paint mPaintMove;
    private String []array={"A","B","C","D","E","F","G",
            "H","I","J","K","L","M","N","O","P","Q","R",
            "S","T","U","V","W","X","Y","Z"};
    private int count=1;
    private int index;

    private OnItemOnClick listener;

    public void setListener(OnItemOnClick listener) {
        this.listener = listener;
    }

    public interface OnItemOnClick{
        public void onItemOnClickListener(int index,String indexString);
    }
    public MySilder(Context context) {
        super(context);
    }

    public MySilder(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPaint=new Paint();
        mPaint.setTextAlign(Paint.Align.CENTER);
        mPaintMove=new Paint();
        mPaintMove.setTextAlign(Paint.Align.CENTER);
        mPaintMove.setColor(Color.RED);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width=getDefaultSize(getSuggestedMinimumWidth(),widthMeasureSpec);
        height=getDefaultSize(getSuggestedMinimumHeight(),heightMeasureSpec);
        setMeasuredDimension(width,height);//設置畫布的大小,長和寬
    //設置字體的大小
        mPaint.setTextSize(height/26);
        mPaintMove.setTextSize(height/26);
    }

    private  float x,y;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()){
            case MotionEvent.ACTION_MOVE:
            case MotionEvent.ACTION_DOWN:
                x=event.getX();
                y=event.getY();
                if (x>width-mPaint.measureText("M")*2) {
                    index = (int) (y / (height / 26));
                    invalidate();
                    if (listener!=null){
                        listener.onItemOnClickListener(index ,array[index]);
                    }
                    return true;
                }
                    break;
            case MotionEvent.ACTION_UP:
                count=-1;
                invalidate();
                return true;
        }
        return super.onTouchEvent(event);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        for (int i=0;i<26;i++){
            canvas.drawText(array[i],width-mPaint.measureText("M"),height/26*(i+1),mPaint);
            if (count==1){
                canvas.drawText(array[index],width-mPaint.measureText("M"),height/26*(index+1),mPaint);
            }else{
                canvas.drawText(array[index],width-mPaint.measureText("M"),height/26*(index+1),mPaintMove);
            }
        }
    }
}

MySilderActivity.java

public class MySilderActivity extends Activity {
    private TextView mTextView;
    private MySilder mySilder;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_silder);
        mTextView= (TextView) findViewById(R.id.textview);
        mySilder= (MySilder) findViewById(R.id.silder);
        mySilder.setListener(new MySilder.OnItemOnClick() {
            @Override
            public void onItemOnClickListener(int index,String indexString) {
                mTextView.setText(indexString);
            }
        });
    }
}

activity_silder.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:textSize="100dp"
        android:text="A"
        android:textAlignment="center"/>
<com.example.administrator.canvas.widget.MySilder
    android:id="@+id/silder"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"/>
</RelativeLayout>

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章