Android自定義控制元件view(草稿版)
阿新 • • 發佈:2018-12-18
Ⅰ、繼承現有控制元件,對其控制元件的功能進行拓展。(拓展功能)
Ⅱ、將現有控制元件進行組合,實現功能更加強大控制元件。(佈局重用)
Ⅲ、重寫View實現全新的控制元件(不規則效果控制元件)
本文來討論最難的一種自定義控制元件形式,重寫View來實現全新的控制元件。
1.構造方法,1參,2參,3參(4參的一般不用)
2.
onMeasure(int widthMeasureSpec, int heightMeasureSpec)測繪大小
onDraw(Canvas canvas)用Canvas和Paint繪製內容
onLayout(boolean changed,int left, int top, int right, int bottom)確定顯示的位置
onTouchEvent(MotionEvent event)定義觸控事件
private int mColor01; public CustomView01(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); //構造方法獲取自定義屬性的方法 TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.CustomView01); //若第一個引數為null,預設值為RED mColor01=a.getColor(R.styleable.CustomView01_textColor,Color.RED); //關閉資源 a.recycle(); }
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //先宣告兩個int值來表示最終的width和height並給定一個預設的大小 int width_size = 500; int height_size = 500; //使用MeasureSpec分別獲取width和height的MODE和SIZE int HEIGHT_MODE = MeasureSpec.getMode(heightMeasureSpec); int HEIGHT_SIZE = MeasureSpec.getSize(heightMeasureSpec); int WIDTH_MODE = MeasureSpec.getMode(widthMeasureSpec); int WIDTH_SIZE = MeasureSpec.getSize(widthMeasureSpec); //這個方法的用途是因為自定義view的wrap_content屬性失效的使用方法 //setMeasuredDimension用於設定view的寬高 if (getLayoutParams().width == ViewGroup.LayoutParams.WRAP_CONTENT && getLayoutParams().height == ViewGroup.LayoutParams.WRAP_CONTENT) { setMeasuredDimension(width_size, height_size); } else if (getLayoutParams().width == ViewGroup.LayoutParams.WRAP_CONTENT) { setMeasuredDimension(width_size, WIDTH_SIZE); } else if (getLayoutParams().height == ViewGroup.LayoutParams.WRAP_CONTENT) { setMeasuredDimension(HEIGHT_SIZE, height_size); } }
MeasureSpect三種模式
MeasureSpect是由LayoutParameter通過父容器的施加的規則產生的
MeasureSpec.EXACTLY MeasureSpec.AT_MOST MeasureSpec.UNSPECIFIED這三種模式
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// // 畫文字
// canvas.drawText();
// // 畫弧
// canvas.drawArc();
// // 畫圓
// canvas.drawCircle();
canvas.drawColor(Color.RED); //設定canvas的背景色
float radius = 50; //給定半徑
//給定圓心的的座標
float cx = 50;
float cy = 50;
Paint paint1 = new Paint(); //例項化一個Paint物件
paint1.setColor(Color.BLUE); //設定圓的顏色
//通過canvas的drawCircle方法畫一個圓圈.
// canvas.drawCircle(cx, cy, radius, paint1);
Paint paint2 = new Paint(); //例項化一個Paint物件
paint2.setColor(Color.BLACK);
paint2.setStrokeWidth(10);//因為預設實在是太細了 設定了一個寬度值
canvas.drawLine(0, 0, 100, 100, paint2);
Paint paint3 = new Paint(); //例項化一個Paint物件
paint3.setColor(Color.BLACK); //設定圓的顏色
paint3.setAntiAlias(true); //設定抗鋸齒
paint3.setStyle(Paint.Style.FILL); //設定樣式
paint3.setStrokeWidth(3); //設定寬度
Paint paint4 = new Paint(); //例項化第二個paint物件
paint4.setColor(Color.BLUE); //設定顏色為藍色
paint4.setStyle(Paint.Style.STROKE);//設定樣式
paint4.setStrokeWidth(30); //設定邊框寬度
//通過canvas的drawCircle方法畫一個圓圈.
canvas.drawCircle(cx, cy, radius, paint3);
canvas.drawCircle(cx, cy, radius, paint4);
}
Paint.setStyle三種樣式,填充,填充和外輪廓,外輪廓
FILL,FILL_OR_STROKE,或STROKE
Paint的set和Canvas的set詳細參考底下
https://www.cnblogs.com/itgungnir/p/6217447.html
@Override
protected void onLayout(boolean changed,int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// 手指按下
Log.e("TAG", "手指按下");
break;
case MotionEvent.ACTION_MOVE:
// 手指移動
Log.e("TAG", "手指移動");
break;
case MotionEvent.ACTION_UP:
// 手指擡起
Log.e("TAG", "手指擡起");
break;
default:
break;
}
return super.onTouchEvent(event);
}
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CustomView01">
<attr name="textSize" format="dimension" />
<attr name="text" format="string" />
<attr name="circleColor" format="color" />
<attr name="arcColor" format="color" />
<attr name="textColor" format="color" />
<attr name="startAngle" format="integer" />
<attr name="sweepAngle" format="integer" />
</declare-styleable>
</resources>