Android不同汉字字数对齐
在布局中进行使用到空格,以便实现文字的对齐。那么在中如何表示一个空格呢?
一个汉字宽度的空格: ‒【用两个空格( )占一个汉字的宽度时,两个空格比一个汉字略窄,三个空格( )比一个汉字略宽】
在实际使用中需要灵活使用 和 的组合。
:text="真实姓名:"
:text="身 份 证:"
:text="姓 ‒名:"
android:text="身份证:"
实现首行缩进的方法:
以上转载自布局中的空格以及占一个汉字宽度的空格的实现_七色音阶的博客-CSDN博客
这么写有一个问题,我在使用 ‒时候部分机型转译虎不是空格,而是“-”。
又发一种形式 半个中文字更准确点, 一个中文字但用起来会比中文字宽一点点。 所以中文对齐还是建议使用 , 而 在不同机型有不同表现。
这种形式只适用于半个字符拼接。如果不是半个就不行了。只能自己计算字符宽度
常見一個工具类,使用时直接
SpannableStringBuilder retailName = AlignedTextUtils.justifyString("身份证", 4); retailName.append(":"); tvName.setText(retailName);
public class AlignedTextUtils {private static int n = 0;// 原Str拥有的字符个数private static SpannableString spannableString;private static double multiple = 0;// 放大倍数/*** 对显示的字符串进行格式化 比如输入:出生年月 输出结果:出正生正年正月*/public static String formatStr(String str) {if (TextUtils.isEmpty(str)) {return "";}str = ToSBC(str);n = str.length()-1;if (n >= 4) {return str;}StringBuilder sb = new StringBuilder(str);for (int i = n - 1; i > 0; i--) {sb.insert(i, "正");}return sb.toString();}/*** 对显示字符串进行格式化 比如输入:安正卓正机正器正人 输出结果:安 卓 机 器 人** @param str* @return */public static SpannableString formatText(String str) {if (TextUtils.isEmpty(str)) {return null;}str = formatStr(str);if (str.length() <= 4) {return null;}spannableString = new SpannableString(str);switch (n) {case 3:multiple = 0.3333333333333333333333333333333333;break;default:break;}for (int i = 1; i < str.length()-1; i = i + 2){spannableString.setSpan(new RelativeSizeSpan((float) multiple), i, i + 1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);spannableString.setSpan(new ForegroundColorSpan(Color.TRANSPARENT), i, i + 1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);}return spannableString;}/**转全角的方法(SBC case)
全角空格为12288,半角空格为32其他字符半角(33-126)与全角(65281-65374)的对应关系是:均相差65248* @param input 任意字符串* @return 半角字符串**/public static String ToSBC(String input){//半角转全角:char[] c=input.toCharArray();for (int i = 0; i < c.length; i++){if (c[i]==32){c[i]=(char)12288;continue;}if (c[i]<127)c[i]=(char)(c[i]+65248);}return new String(c);}public static SpannableStringBuilder justifyString(String str, int num) {SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder();if (TextUtils.isEmpty(str)) {return spannableStringBuilder;}char[] chars = str.toCharArray();if (chars.length >= num || chars.length == 1) {return spannableStringBuilder.append(str);}int l = chars.length;float scale = (float) (num - l) / (l - 1);for (int i = 0; i < l; i++) {spannableStringBuilder.append(chars[i]);if (i != l - 1) {SpannableString s = new SpannableString(" ");//全角空格s.setSpan(new ScaleXSpan(scale), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);spannableStringBuilder.append(s);}}return spannableStringBuilder;}
}
如果布局用到的地方太多,每一个都要给一个ID,实例化后在进行设置,代码显得过于臃肿,可以集成进自定义view中。
@SuppressLint("AppCompatCustomView")
public class AlignedTextView extends TextView {private static int n = 0;// 原Str拥有的字符个数private static SpannableString spannableString;private static double multiple = 0;// 放大倍数//显示文本private String text;public AlignedTextView(Context context, AttributeSet attrs) {super(context, attrs);init(context,attrs);}public AlignedTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init(context,attrs);}public AlignedTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {super(context, attrs, defStyleAttr, defStyleRes);init(context,attrs);}private void init(Context context, AttributeSet attrs){//获取自定义属性TypedArray typeArray = context.obtainStyledAttributes(attrs, R.styleable.AlignedText);if (typeArray != null) {n = typeArray.getInteger(R.styleable.AlignedText_textNum,4);text= typeArray.getString(R.styleable.AlignedText_TextView_text);SpannableStringBuilder spannableStringBuilder = justifyString(text, n);setText(spannableStringBuilder);//回收typeArray.recycle();}}/*** 对显示的字符串进行格式化 比如输入:出生年月 输出结果:出正生正年正月*/public static String formatStr(String str) {if (TextUtils.isEmpty(str)) {return "";}str = ToSBC(str);n = str.length()-1;if (n >= 4) {return str;}StringBuilder sb = new StringBuilder(str);for (int i = n - 1; i > 0; i--) {sb.insert(i, "正");}return sb.toString();}/*** 对显示字符串进行格式化 比如输入:安正卓正机正器正人 输出结果:安 卓 机 器 人** @param str* @return */public static SpannableString formatText(String str) {if (TextUtils.isEmpty(str)) {return null;}str = formatStr(str);if (str.length() <= 4) {return null;}spannableString = new SpannableString(str);switch (n) {case 3:multiple = 0.3333333333333333333333333333333333;break;default:break;}for (int i = 1; i < str.length()-1; i = i + 2){spannableString.setSpan(new RelativeSizeSpan((float) multiple), i, i + 1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);spannableString.setSpan(new ForegroundColorSpan(Color.TRANSPARENT), i, i + 1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);}return spannableString;}/**转全角的方法(SBC case)
全角空格为12288,半角空格为32其他字符半角(33-126)与全角(65281-65374)的对应关系是:均相差65248* @param input 任意字符串* @return 半角字符串**/public static String ToSBC(String input){//半角转全角:char[] c=input.toCharArray();for (int i = 0; i < c.length; i++){if (c[i]==32){c[i]=(char)12288;continue;}if (c[i]<127)c[i]=(char)(c[i]+65248);}return new String(c);}public SpannableStringBuilder justifyString(String str, int num) {SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder();if (TextUtils.isEmpty(str)) {return spannableStringBuilder;}char[] chars = str.toCharArray();if (chars.length >= num || chars.length == 1) {return spannableStringBuilder.append(str);}int l = chars.length;float scale = (float) (num - l) / (l - 1);for (int i = 0; i < l; i++) {spannableStringBuilder.append(chars[i]);if (i != l - 1) {SpannableString s = new SpannableString(" ");//全角空格s.setSpan(new ScaleXSpan(scale), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);spannableStringBuilder.append(s);}}return spannableStringBuilder;}
}