自定义View类
* author:Created by WangZhiQiang on 2017/12/26.
*/
public class TextView1 extends View {
private String content;
private int color;
private float size;
private Paint paint;
private int rawX;
private int rawY;
private int mX;
private int mY;
public TextView1(Context context) {
this(context, null);
}
public TextView1(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public TextView1(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//获取布局文件中的属性,将属性绘制在控件中
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.myTextView, defStyleAttr, 0);
//取出属性,获取字符串
content = typedArray.getString(R.styleable.myTextView_content);
color = typedArray.getColor(R.styleable.myTextView_myColor, Color.RED);
size = typedArray.getDimension(R.styleable.myTextView_mySize, 30);
//初始化画笔
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(color);
paint.setTextSize(size);
}
@SuppressLint("DrawAllocation")
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Rect rect = new Rect();
paint.getTextBounds(content, 0, content.length(), rect);
canvas.drawText(content, 0, rect.height(), paint);
}
@SuppressLint("DrawAllocation")
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//获取测量的模式和测量的尺寸
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
//如果测量模式是EXACTLY就直接显示测量尺寸
int width;
int height;
if (widthMode == MeasureSpec.EXACTLY) {
width = widthSize;
} else {
//控件的宽度 = 文字的宽度+左右边距
Rect rect = new Rect();
paint.getTextBounds(content, 0, content.length(), rect);
int width1 = rect.width();
width = width1 + getPaddingLeft() + getPaddingRight();
}
//高度
if (heightMode == MeasureSpec.EXACTLY) {
height = heightSize;
} else {
//控件的高度 = 文字的高度+上下边距
Rect rect = new Rect();
paint.getTextBounds(content, 0, content.length(), rect);
int height1 = rect.height();
height = height1 + getPaddingBottom() + getPaddingTop();
}
//给宽高重新赋值
setMeasuredDimension(width, height);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case 0: //按下
//获取绝对位置
rawX = (int) event.getRawX();
rawY = (int) event.getRawY();
break;
case 1: //移动
mX = (int) event.getRawX();
int dX = mX - rawX;
mY = (int) event.getRawY();
int dY = mY - rawY;
//将间距加上原来的位置=移动的距离
int l = getLeft();
int r = getRight();
int t = getTop();
int b = getBottom();
l = l + dX;
r = r + dX;
t = t + dY;
b = b + dY;
//重新布局
layout(l, t, r, b);
//重新赋值初始化位置
rawX = mX;
rawY = mY;
break;
case 2: //抬起
// Toast.makeText(getContext(), "我抬起了!!!", Toast.LENGTH_SHORT).show();
break;
}
return true;
}
}
自定义布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:myattr="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.anshuangxin.zidingyitextview.MainActivity">
<com.anshuangxin.zidingyitextview.TextView1
android:id="@+id/myTextView"
myattr:content="我的文字haha~"
android:background="#ff0000"
myattr:myColor="#0f0"
myattr:mySize="25sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
attrs.xml文件(自定义属性)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--定义属性-->
<attr name="content" format="string"/>
<attr name="myColor" format="color"/>
<attr name="mySize" format="dimension"/>
<!--将定义好的属性放入属性列表中-->
<declare-styleable name="myTextView">
<attr name="content"/>
<attr name="myColor"/>
<attr name="mySize"/>
</declare-styleable>
</resources>