繪製簡單圖形
下面是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>