Android不同汉字字数对齐

本文介绍在Android开发中实现文本对齐的方法,包括使用特殊字符实现等宽对齐,及自定义视图实现动态文本调整。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


在Android布局中进行使用到空格,以便实现文字的对齐。那么在Android中如何表示一个空格呢?

  • 空格: 
  • 窄空格:‒

一个汉字宽度的空格:  ‒【用两个空格(  )占一个汉字的宽度时,两个空格比一个汉字略窄,三个空格(   )比一个汉字略宽】

在实际使用中需要灵活使用 和 的组合。

android:text="真实姓名:"

android:text="身    证:"

android:text="姓  ‒名:"

android:text="身份证:" 

TextView实现首行缩进的方法:

  • 在string资源文件中,在文字的前面加入”\u3000\u3000”即可实现首行缩进
  • 在Java代码中,使用setText("\u3000\u3000"+xxxxx);

以上转载自Android布局中的空格以及占一个汉字宽度的空格的实现_七色音阶的博客-优快云博客

这么写有一个问题,我在使用  ‒时候部分机型转译虎不是空格,而是“-”。

又发一种形式  半个中文字更准确点,  一个中文字但用起来会比中文字宽一点点。 所以中文对齐还是建议使用 , 而   在不同机型有不同表现

这种形式只适用于半个字符拼接。如果不是半个就不行了。只能自己计算字符宽度

常見一個工具类AlignedTextUtils,使用时直接

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)<br/><br/>
     全角空格为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;
    }
}

如果布局用到TextView的地方太多,每一个TextView都要给一个ID,实例化后在进行设置,代码显得过于臃肿,可以集成进自定义view中。

<com.demo.view.AlignedTextView
    app:TextView_text="三个字"
    app:textNum="4"
    android:textColor="@color/black"
    android:layout_height="match_parent"
    android:layout_width="wrap_content"
   />

 <declare-styleable name="AlignedText">
        <attr name="textNum" format="integer" />
        <attr name="TextView_text" format="string" />
    </declare-styleable>

@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)<br/><br/>
     全角空格为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;
    }
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值