作者:王慧1019 | 来源:互联网 | 2023-02-10 19:38
搜索了一下关于android字间距,文章很多,但是真正能用的很少,刚好今天有这样的需求,参考了一下网上其它人的写法,自己写了一个,顺便开放源代码,供大家参考。别人写的自定义的textv
搜索了一下关于android字间距,文章很多,但是真正能用的很少,刚好今天有这样的需求,参考了一下网上其它人的写法,自己写了一个,顺便开放源代码,供大家参考。
别人写的自定义的textview一般都有问题,少了一步计算textview控件的宽度的方法,少了一个计算文本居中对齐的方法所以写出来的文字是竖向排列的,
网上很多人说textView有一个属性android:textScaleX是调节字间距的,它的值是一个float型。这是错误的。真正的字间距需要自己去继承textview实现。
package com.huifeng.bufu.widget;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.huifeng.bufu.R;
import com.huifeng.bufu.tools.Tool;
import android.content.Context;
import android.graphics.*;
import android.graphics.Paint.FontMetrics;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.TextView;
public class MyTextView extends TextView {
private Context context;
private String content;
private int Twidth;
private int Lwidth;
private int xstart;
private TextPaint paint;
private int xPadding;
private int yPadding;
private int textHeight;
private int xPaddingMin;
private String strr;
int count;
// 记录每个字的二维数组
int[][] position;
public MyTextView(Context context) {
super(context);
this.cOntext= context;
init();
}
public MyTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.cOntext= context;
init();
}
public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
this.cOntext= context;
init();
}
public void setText(String str) {
//拿到你传进来的文本值
this.strr=str;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
if (widthMode == MeasureSpec.EXACTLY
|| widthMode == MeasureSpec.AT_MOST) {
//获取你textview控件的宽,方便做文字对齐的,如果你的textview控件需要设置宽高,也是在这里设置的
Lwidth = widthSize;
Twidth = strr.length()*Tool.dpToPx(context, 30);//算出所有文本的总宽度,因为我这里就只有一行字,并且居中对齐
xstart = (Lwidth-Twidth)/2;//算出第一个文字的其实位置
Log.i("MyTextView", "Lwidth"+Lwidth);
getPositions(strr);//获取每一个文字的位置信息
this.postInvalidate();//绘制
} else {
}
}
public void init() {
paint = new TextPaint();
paint.setColor(getResources().getColor(R.color.red));
paint.setTypeface(Typeface.DEFAULT);
paint.setTextSize(Tool.dpToPx(context, 30));
FontMetrics fm = paint.getFontMetrics();// 得到系统默认字体属性
textHeight = (int) (Math.ceil(fm.descent - fm.top) + 2);// 获得字体高度
// 字间距
xPadding = dip2px(this.getContext(), 4f);
// 行间距
yPadding = dip2px(this.getContext(), 10f);
// 比较小的字间距(字母和数字应紧凑)
xPaddingMin = dip2px(this.getContext(), 2f);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//画出每一个文字
if (!TextUtils.isEmpty(content)) {
for (int i = 0; i Lwidth) {
lineNum++;// 真实的行数加一
x = xstart+Tool.dpToPx(context, 30)/2;
} else {
// 回到预判前的位置
x -= textWith;
}
// 记录每一个字的位置
position[i][0] = x;
position[i][1] = textHeight * lineNum + yPadding * (lineNum - 1);
Log.i("MyTextView", "position[i][1]"+position[i][0]);
// 判断是否是数字还是字母 (数字和字母应该紧凑点)
// 每次输入完毕 进入下一个输入位置准备就绪
if (isNumOrLetters(str)) {
x += textWith + xPaddingMin;
} else {
x += textWith + xPadding;
}
}
// 根据所画的内容设置控件的高度
this.setHeight((textHeight + yPadding) * lineNum);
}
// 工具类:判断是否是字母或者数字需要的话可以引用
public boolean isNumOrLetters(String str) {
String regEx = "^[A-Za-z0-9_]+$";
Pattern p = Pattern.compile(regEx);
Matcher m = p.matcher(str);
return m.matches();
}
// 工具类:在代码中使用dp的方法(因为代码中直接用数字表示的是像素)
public static int dip2px(Context context, float dip) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dip * scale + 0.5f);
}
}
有一点需要注意,一下,给这个控件setText的时候,一定要调用这个控件的setText(String str),而不是调用textview的setText(CharSequence text)这个方法,否则无法显示自定义的文本间距。