閑來無事,擼了一個自定義view隨機(jī)數(shù),也算是學(xué)習(xí)啦
class TestView : View {
constructor(context: Context) : super(context) {
init(context, null);
}
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
init(context, attrs);
}
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
init(context, attrs);
}
private var textSize: Int = 0;
private var textTest: String = "";
private var textColor: Int = 0;
private var mPain: Paint? = null;
private var mBound: Rect? = null;
private fun init(context: Context, attrs: AttributeSet?) {
//獲取控件中包含的屬性
val typeArray = context.obtainStyledAttributes(attrs, R.styleable.text_view);
//分別獲取設(shè)置的值
val indexCount = typeArray.indexCount
(0..indexCount).map { typeArray.getIndex(it) }.forEach {
when (it) {
R.styleable.text_view_titleTextSize -> {
textSize = typeArray.getDimensionPixelSize(it, 16)
}
R.styleable.text_view_titleText -> {
textTest = typeArray.getString(it);
}
R.styleable.text_view_titleColor -> {
textColor = typeArray.getColor(it, Color.BLACK);
}
}
}
typeArray.recycle(); //此方法即使回收獲取屬性,避免內(nèi)存泄漏
mPain = Paint();
mPain!!.textSize = textSize.toFloat();
mBound = Rect();
mPain!!.getTextBounds(textTest, 0, textTest.length, mBound);
//設(shè)置控件點擊事件
setOnClickListener {
textTest = randomText();
postInvalidate(); //重新繪制該方法調(diào)用后只會調(diào)用onDraw方法
}
}
/**
* 處理布局文件中設(shè)置wrap_content時view滿屏問題
* 系統(tǒng)默認(rèn)測量寬高為match_parent
* MeasureSpec分為三種模式:
* EXACTLY設(shè)置確切的值或Match_parent
* AT_MOST布局限制在最大的值wrap_content
* UNSPECIFIED 布局想要多大可以多大,一般為源碼所用
*/
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
var width: Int;
var height: Int;
val widthMode = MeasureSpec.getMode(widthMeasureSpec);
val widthSize = MeasureSpec.getSize(widthMeasureSpec);
val heightMode = MeasureSpec.getMode(heightMeasureSpec);
val heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (widthMode == MeasureSpec.EXACTLY) {
width = widthSize;
} else {
mPain!!.textSize = textSize.toFloat();
mPain!!.getTextBounds(textTest, 0, textTest.length, mBound);
val textWidth = mBound!!.width();
width = paddingLeft + textWidth + paddingRight;
}
if (heightMode == MeasureSpec.EXACTLY) {
height = heightSize;
} else {
mPain!!.textSize = textSize.toFloat();
mPain!!.getTextBounds(textTest, 0, textTest.length, mBound);
val textHeight = mBound!!.height();
height = paddingBottom + paddingTop + textHeight;
}
setMeasuredDimension(width, height); //設(shè)置最終測量寬高
}
/**
* 繪制界面方法
* 盡量不要在view中做耗時操作
*/
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
mPain!!.color = Color.YELLOW //繪制背景
canvas.drawRect(0f, 0f, measuredWidth.toFloat(), measuredHeight.toFloat(), mPain);
mPain!!.color = Color.GREEN //繪制文字
canvas.drawText(textTest, (width / 2 - mBound!!.width() / 2).toFloat(), (height / 2 + mBound!!.height()/2).toFloat(), mPain)
}
private fun randomText(): String {
val random = Random();
var set = HashSet<Int>();
while (set.size < 4){
val randomInt = random.nextInt(10);
set.add(randomInt)
}
val sb= StringBuffer();
for (item in set){
sb.append(""+item)
}
return sb.toString();
}
}