自己写下的思路,为了方便。
注意点:在不同构造方法里面写上下面对应的话,不然会报错
this(context, null);
this(context, attrs, 0);
//获取完属性以后要释放资源
typedArray.recycle();
onMeasure里面测量的三种模式
-
UNSPECIFIED(未指定),父控件对子控件不加任何束缚,子元素可以得到任意想要的大小,这种MeasureSpec一般是由父控件自身的特性决定的。比如ScrollView,它的子View可以随意设置大小,无论多高,都能滚动显示,这个时候,size一般就没什么意义。EXACTLY(完全),父控件为子View指定确切大小,希望子View完全按照自己给定尺寸来处理,跟上面的场景1跟2比较相似,这时的MeasureSpec一般是父控件根据自身的MeasureSpec跟子View的布局参数来确定的。一般这种情况下size>0,有个确定值。AT_MOST(至多),父控件为子元素指定最大参考尺寸,希望子View的尺寸不要超过这个尺寸,跟上面场景3比较相似。这种模式也是父控件根据自身的MeasureSpec跟子View的布局参数来确定的,一般是子View的布局参数采用wrap_content的时候
-
界面刷新是要调用postInvalidate();
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import java.util.HashSet;
import java.util.Random;
/**
* Created by Administrator on 2017/9/15.
*/
public class CustomTextView extends View{
// 文字
private String mTitleText;
// 文字颜色
private int mTitleTextColor;
// 字号
private int mTitleTextSize;
private Rect mBound;
private Paint paint;
public CustomTextView(Context context) {
this(context, null);
Log.e("-----CustomTitleView:", "111");
}
public CustomTextView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
Log.e("-----CustomTitleView:", "222");
}
public CustomTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
Log.e("-----CustomTitleView:", "333");
/**
* 获得我们所定义的自定义样式属性
*/
TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomTextView, defStyleAttr, 0);
int n = typedArray.getIndexCount();
for (int i=0;i<n;i++){
//获取单个属性的值的ID
int aar = typedArray.getIndex(i);
switch (aar) {
case R.styleable.CustomTextView_titleText :
mTitleText = typedArray.getString(aar);
break;
case R.styleable.CustomTextView_titleTextColor:
mTitleTextColor = typedArray.getColor(aar, Color.BLACK);
break;
case R.styleable.CustomTextView_titleTextSize :
//typedArray.getDimensionPixelSize这个方法是获得int,
//typedArray.getDimension这个方法是获得float,
mTitleTextSize = typedArray.getDimensionPixelSize(aar, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));
break;
default:
break;
}
}
//获取完属性以后要释放资源
typedArray.recycle();
// 获取文本的宽高
paint = new Paint();
paint.setTextSize(mTitleTextSize);
mBound = new Rect();
paint.getTextBounds(mTitleText,0,mTitleText.length(), mBound);
//点击事件
this.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
mTitleText=randdomText();
postInvalidate();
}
});
}
public String randdomText(){
Random random = new Random();
HashSet<Integer> integers = new HashSet<>();
while(integers.size()<4){
int randomint = random.nextInt(100);
integers.add(randomint);
}
StringBuffer stringBuffer = new StringBuffer();
for (Integer i:integers){
stringBuffer.append("").append(i);
}
return stringBuffer.toString();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthmode = MeasureSpec.getMode(widthMeasureSpec);
int widthsize = MeasureSpec.getSize(widthMeasureSpec);
int heightmode = MeasureSpec.getMode(heightMeasureSpec);
int heightsize = MeasureSpec.getSize(heightMeasureSpec);
int width=0;
int height=0;
switch (widthmode) {
case MeasureSpec.EXACTLY:
width = getPaddingLeft() + getPaddingRight() + widthsize;
break;
case MeasureSpec.AT_MOST:
case MeasureSpec.UNSPECIFIED:
float textWidth = paint.measureText(mTitleText);
width = (int) (getPaddingLeft() + getPaddingRight() + textWidth);
break;
}
switch (heightmode) {
case MeasureSpec.EXACTLY:
height = getPaddingLeft() + getPaddingRight() + heightsize;
break;
case MeasureSpec.AT_MOST:
case MeasureSpec.UNSPECIFIED:
// int textHeight = mRect.height(); //直接计算出来的会有误差
Paint.FontMetrics fontMetrics = paint.getFontMetrics();
// float textHeight = Math.abs((fontMetrics.descent - fontMetrics.ascent));
float textHeight = Math.abs((fontMetrics.bottom - fontMetrics.top));
height = (int) (getPaddingTop() + getPaddingBottom() + textHeight);
break;
}
setMeasuredDimension(width,height);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setColor(Color.YELLOW);
canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),paint);
paint.setColor(mTitleTextColor);
canvas.drawText(mTitleText,getWidth() / 2 - mBound.width() / 2, getHeight() / 2 + mBound.height() / 2, paint);
}
}