高階介面之自定義View的使用
阿新 • • 發佈:2018-12-24
自定義View
建立自定義控制元件步驟
繼承View,重寫onDraw(Canvas)方法,繪製自定義控制元件。
在layout_main佈局檔案中新增自定義View標籤。
得到自定義控制元件的寬和高(長度以畫素為單位)
this.getWidth(); this.getHeight();
Canvas畫布類
繪製向量圖
繪製線段
canvas.drawLine(startX,startY,endX,endY,paint);
繪製矩形
canvas.drawRect(left,top,right,bottom,paint);
繪製圓
canvas.drawCircle (x,y,radius,paint);
繪製路徑
Path path=new Path();//要想繪製折線圖,把畫筆設為空心path沒有
path.moveTo(0,300);// 關閉
path.lineTo(100,800);
path.lineTo(500,800);
canvas.drawPath(path,paint);
繪製文字
canvas.drawText(text,x,y,paint);//文字的錨點座標在左下角
繪Canvas.drawBitmap(bitmap,x,y,paint);//圖片的錨點座標在左上角布
canvas.save();//儲存畫布
canvas.clipRect(0,0,200 ,100);//設定裁剪區域
canvas.drawCircle(100,100,100,paint);//在畫布上繪製圖形
canvas.restore();//恢復畫布
Paint畫筆類
設定畫筆顏色
paint.setColor(Color.BLACK);
消除畫筆鋸齒
paint.setAntiAlias(true);
設定畫筆樣式
//實心畫筆
paint.setStyle(Style.FILL);
//空心畫筆
paint.setStyle(Style.STROKE);
- 自定義View的事件監聽
- 重寫onTouchEvent方法,監聽使用者事件
- 獲取使用者觸控點座標
- event.getX(); event.getY();
獲取使用者觸控動作
event.getAction();
使用者動作
MotionEvent.ACTION_DOWN//按下
MotionEvent.ACTION_UP//鬆開
MotionEvent.ACTION_MOVE//移動
**注意:如果要求捕獲全部動作,需要將onTouchEvent方法的返回值設定為true
重新整理控制元件介面**
在主執行緒中使用
this.invalidate();//在主執行緒中使用重新整理介面
在子執行緒中使用
this.postInvalidate();
例項:點選螢幕上的位置,每點選一次就得到一個圓
如圖所示:
程式碼:
MainActivity.class
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<com.example.MyView
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
MyView.java
import java.util.ArrayList;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
public class MyView extends View {
Paint paint = new Paint();
ArrayList<Point> point=new ArrayList<Point>();
int radius=50;
//儲存圓心座標
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.BLACK);
paint.setColor(Color.WHITE);
//畫圓
for(int i=0;i<point.size();i++){
canvas.drawCircle(point.get(i).getX(),point.get(i).getY(),radius, paint);
}
}
// 當用戶觸控控制元件時,系統呼叫該方法
@Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
// 獲取觸控點座標
Log.d("Tag", "(" + x + "," + y + ")");
// 觸控動作 (按下,鬆開,滑動)
//觸控動作,預設只能檢測到down。
//如果想檢測另外兩個動作,必須將返回值改為true
if (event.getAction() == MotionEvent.ACTION_DOWN) {
Log.d("Tag", "down");
point.add(new Point(x, y));
//傳送訊息,讓系統自動呼叫onDraw方法
this.invalidate();
} else if (event.getAction() == MotionEvent.ACTION_UP) {
Log.d("Tag", "up");
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
Log.d("Tag", "move");
}
return true;
}
}
Point.java
public class Point {
int x;
int y;
public Point(int x,int y){
this.x=x;
this.y=y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}