资料参考文档
需求
公司需要文字下面有个线,这个线要有颜色
学习到的知识点
1、如何获取文字的宽度?
Rect bounds = new Rect();
TextPaint paint = this.getPaint();
paint.getTextBounds(this.getText().toString(),0,this.getText().toString().length(),bounds);
bounds.width();//文字的宽度
2、根据文字所在矩形的中间线,求出baseLine的位置,文字所在的中间线,目前就是我们这个TextView的高度,然后我们根据公式来套用求出baseLine,公式如下
baseLine = center + (FontMetrics.bottom - FontMetrics.top)/2 一 FontMetrics.bottom
3、需要知道FontMetrics.bottom、FontMetrics.top是直接可以获取到的
Paint.FontMetricsInt fm = mPaint.getFontMetricsInt();
fm.bottom
这些值我们在设置字符串的时候就可以拿到,关键问题是baseLine我们是要计算才可以拿到。还有一个重要点知识点需要知道,如下
Paint.FontMetricsInt fm = mPaint.getFontMetricsInt();
fm.ascent = ascent线的y坐标 - baseLine线的y坐标
谁减谁一定是 ascent线 - baseLine线的y坐标,同理其它的线也是这样子
遇到的问题
1、在增加高度的时候,底部的颜色标签会被排挤到底部,导致不见
问题是处在计算高度的时候,没有将bottlineTop与bottlineHeight纳入计算当中导致的
全部代码展示
xml代码
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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">
<com.example.gao.myapplication.MyTextView
android:layout_width="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginTop="20dp"
android:layout_height="45dp"
android:textSize="16sp"
android:gravity="center"
app:bottlineLeftRightReduce="2dp"
app:bottlineColor="@color/colorAccent"
app:bottlineTop="8dp"
app:bottlineHeight="2dp"
android:text="AAAAA" />
</RelativeLayout>
attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyTextView">
<!--底部下划线的左右边距-->
<attr name="bottlineLeftRightReduce" format="dimension"/>
<!--底部下划线,距离顶部的距离-->
<attr name="bottlineTop" format="dimension"></attr>
<!--底部下划线的颜色-->
<attr name="bottlineColor" format="reference"></attr>
<!--底部下划线的高度-->
<attr name="bottlineHeight" format="dimension"></attr>
</declare-styleable>
</resources>
java代码
public class MyTextView extends android.support.v7.widget.AppCompatTextView {
private String TAG = MyTextView.class.getSimpleName();
private int bottlineHeight = 0;
private int bottlineColor = 0;
private int bottlineLeftRightReduce = 0;//设置左右边距
private int bottlineTop = 0;//底部下划线距离顶部的距离
private Context mContext;
private Paint mPaint;
public MyTextView(Context context) {
this(context, null);
}
public MyTextView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.mContext = context;
TypedArray typedArray = mContext.obtainStyledAttributes(attrs, R.styleable.MyTextView);
bottlineLeftRightReduce = typedArray.getDimensionPixelOffset(R.styleable.MyTextView_bottlineLeftRightReduce, dip2px(2.0f));
bottlineTop = typedArray.getDimensionPixelOffset(R.styleable.MyTextView_bottlineTop, dip2px(0.0f));
bottlineColor = typedArray.getColor(R.styleable.MyTextView_bottlineColor, getResources().getColor(R.color.zi_8C75B3));
bottlineHeight = typedArray.getDimensionPixelOffset(R.styleable.MyTextView_bottlineHeight, dip2px(2.0f));
typedArray.recycle();
mPaint = new Paint();
mPaint.setColor(bottlineColor);
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(bottlineHeight);
mPaint.setStyle(Paint.Style.FILL);
}
public int dip2px(float dipValue) {
final float scale = Resources.getSystem().getDisplayMetrics().density;
return (int) (dipValue * scale + 0.5f);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
setMeasuredDimension(parentWidth, parentHeight + bottlineTop + bottlineHeight);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Rect bounds = new Rect();
TextPaint paint = this.getPaint();
paint.getTextBounds(this.getText().toString(), 0, this.getText().toString().length(), bounds);
int center = getMeasuredHeight() / 2;
int baseLine = (int) (center + (paint.getFontMetrics().bottom - paint.getFontMetrics().top)/2 - paint.getFontMetrics().bottom );
int bottom = (int) (baseLine + paint.getFontMetrics().bottom);
int start = (getMeasuredWidth() - bounds.width()) / 2 + bottlineLeftRightReduce * 2;
int end = start + bounds.width() - bottlineLeftRightReduce * 4;
float height =bottom+ bottlineTop;
canvas.drawLine(start, height, end, height, mPaint);
}
}
网友评论