相关文章--原理:
相关文章--实战:
实战:一个非常简单的自定义TextView
一、在values目录下创建attrs.xml文件,在attrs.xml文件中添加自定义TextView的自定义属性
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="PhTextView">
<attr name="phTextColor" format="color" />
<attr name="phTextSize" format="dimension" />
<attr name="phText" format="string" />
<attr name="phTextMaxLength" format="integer" />
</declare-styleable>
</resources>
二、创建自定义的TextView类
public class PhTextView extends View {
private Paint mPaint;
private String mText;
private int mTextColor;
private int mTextSize = 18;
public PhTextView(Context context) {
this(context, null);
}
public PhTextView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public PhTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//1.获取自定义的属性
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.PhTextView);
mText = typedArray.getString(R.styleable.PhTextView_phText);
mTextColor = typedArray.getColor(R.styleable.PhTextView_phTextColor,
getResources().getColor(R.color.light_blue_2e));
mTextSize = typedArray.getDimensionPixelOffset(R.styleable.PhTextView_phTextSize, spToPx(mTextSize));
typedArray.recycle();
mPaint = new Paint();
//抗锯齿
mPaint.setAntiAlias(true);
//设置防抖动
mPaint.setDither(true);
mPaint.setColor(mTextColor);
mPaint.setTextSize(mTextSize);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// 获取 自定义 View 的宽度,高度 的模式
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (widthMode == MeasureSpec.AT_MOST) {
Rect bounds = new Rect();
mPaint.getTextBounds(mText, 0, mText.length(), bounds);
widthSize = bounds.width() + getPaddingLeft() + getPaddingRight();
heightSize = bounds.height() + getPaddingTop() + getPaddingBottom();
}
if (heightMode == MeasureSpec.AT_MOST) {
Rect bounds = new Rect();
mPaint.getTextBounds(mText, 0, mText.length(), bounds);
widthSize = bounds.width() + getPaddingLeft() + getPaddingRight();
heightSize = bounds.height() + getPaddingTop() + getPaddingBottom();
}
setMeasuredDimension(widthSize,heightSize);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//计算基线
Paint.FontMetricsInt fontMetricsInt = mPaint.getFontMetricsInt();
int dy = (fontMetricsInt.bottom - fontMetricsInt.top) / 2 - fontMetricsInt.bottom;
int baseLine = getHeight() / 2 + dy;
int x = getPaddingLeft();
// x: 开始的位置 y:基线
canvas.drawText(mText, x, baseLine, mPaint);
}
/**
* sp 与 px 转换
*/
private int spToPx(int sp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp,
getResources().getDisplayMetrics());
}
}
三、在布局文件中引用自己的TextView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello PhTextView"
android:textSize="18sp" />
<com.gs.common3.activity.bView.customView.PhTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:phText="Hello PhTextView"
app:phTextSize="18sp" />
</LinearLayout>