【问题标题】:How to adjust line height in TextView with multiple type sizes?如何在具有多种字体大小的 TextView 中调整行高?
【发布时间】:2010-06-15 15:28:03
【问题描述】:

我有一个包含 Spannable 字符串的 TextView。该字符串包含一堆文本,其中第一个单词的字体大小是字符串其余部分的两倍。

问题是由于第一个字的大小增加,第一行和第二行之间的行距远大于后续行之间的行距。

http://img.skitch.com/20100615-fwd2aehbsgaby8s2s9psx3wwii.png

可跨字符串是使用以下代码 sn-p 创建的:

    // Price
    CharSequence text = "$30 Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
    final Pattern priceRegex = Pattern.compile("^(.[0-9]+)\\s.*");
    final Matcher m = priceRegex.matcher(text!=null ? text : "");
    if( m.matches() ) {
        text = new SpannableString(text);
        ((SpannableString)text).setSpan(new RelativeSizeSpan(2), 0, m.end(1), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    }

如何修复我的 TextView 以使所有行具有相同的间距?

【问题讨论】:

    标签: android textview


    【解决方案1】:

    您可以尝试使用以下 TextView 属性之一:

    android:lineSpacingMultiplier
    android:lineSpacingExtra
    

    至少尝试使所有行的高度相同(与第一行相同)。

    【讨论】:

    • 不也是按比例倍增第一行的行距吗?
    • 请注意,android:lineSpacingMultiplier 仅在 API 级别 16 及更高版本中可用。
    • 我遇到了完全相同的问题,但此解决方案不起作用。就像@emmby 所说的那样,它确实按比例缩放了 all 行的间距。
    • @yiati : 方法 setLineSpacing()android:lineSpacingMultiplier 可从 API 级别 1 获得。方法 getLineSpacing() 可从 API 级别 16 获得。您可以参考:developer.android.com/reference/android/widget/…
    【解决方案2】:

    经过多次反复试验,我得到了一个非常老套的解决方案:

    1. 我在文本内的每个空格中添加了与强调的单词相同的两倍文本大小的 spannables。这样整个 TextView 就得到了相同的(大)行距。请注意,您不能重复使用 spannable。

    2. 然后我给 TextView 设置了负 lineSpacingExtra,这样行间距又看起来不错了。

    3. 为了避免由于文本大小增加而导致的不自然的宽空间,我为每个空间添加了一个 ScaleXSpan,将它们缩放到原始大尺寸的 50%。

    只要每一行至少包含一个空格字符,此方法甚至适用于保存本地化字符串的 TextView(您永远不知道强调的单词出现在哪个位置或行将多长)。

    【讨论】:

    • 我喜欢你的想法!
    【解决方案3】:

    我写了这个函数:

    输入

    • 线性布局二:

      将成为您的“TexView”的布局(确保其方向是垂直的)

    • 串钱:

      你想要不同的字符串(在你的情况下更大的文本大小)

    • 字符串文本:

      正文

    • 上下文 mContext

      上下文

    做什么

    我评论了你必须编辑的部分


    private void populateText(LinearLayout ll,
            String money, String text , Context mContext) { 
        String [] textArray = text.split(" ");
        Display display = getWindowManager().getDefaultDisplay();
        ll.removeAllViews();
        int maxWidth = display.getWidth() - 20;
    
        LinearLayout.LayoutParams params; // to be used over and over
        LinearLayout newLL = new LinearLayout(mContext);
        newLL.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
                LayoutParams.WRAP_CONTENT));
        newLL.setGravity(Gravity.LEFT);
        newLL.setOrientation(LinearLayout.HORIZONTAL);
    
        int widthSoFar = 0;
    
        ///FIRST INSERT THE MONEY TEXTVIEW
        LinearLayout LL = new LinearLayout(mContext);
        LL.setOrientation(LinearLayout.HORIZONTAL);
        LL.setGravity(Gravity.CENTER_HORIZONTAL|Gravity.BOTTOM); //THIS IS IMPORTANT TO keep spacing up not down
        LL.setLayoutParams(new ListView.LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
    
        TextView TV = new TextView(mContext);
        TV.setText(money);
        //TV.setTextSize(size);  <<<< SET TEXT SIZE
        TV.measure(0, 0);
        params = new LinearLayout.LayoutParams(TV.getMeasuredWidth(),
                LayoutParams.WRAP_CONTENT);
        //params.setMargins(5, 0, 5, 0);  // YOU CAN USE THIS
        LL.addView(TV, params);
        LL.measure(0, 0);
        widthSoFar += TV.getMeasuredWidth();// YOU MAY NEED TO ADD THE MARGINS
        newLL.addView(LL, params);
    
        for (int i = 0 ; i < textArray.length ; i++ ){
            LL = new LinearLayout(mContext);
            LL.setOrientation(LinearLayout.HORIZONTAL);
            LL.setGravity(Gravity.CENTER_HORIZONTAL|Gravity.BOTTOM);
            LL.setLayoutParams(new ListView.LayoutParams(
                    LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
    
            TV = new TextView(mContext);
            TV.setText(textArray[i]);
            //TV.setTextSize(size);  <<<< SET TEXT SIZE
            TV.measure(0, 0);
            params = new LinearLayout.LayoutParams(TV.getMeasuredWidth(),
                    LayoutParams.WRAP_CONTENT);
            //params.setMargins(5, 0, 5, 0);  // YOU CAN USE THIS
            LL.addView(TV, params);
            LL.measure(0, 0);
            widthSoFar += TV.getMeasuredWidth();// YOU MAY NEED TO ADD THE MARGINS
            if (widthSoFar >= maxWidth) {
                ll.addView(newLL);
    
                newLL = new LinearLayout(mContext);
                newLL.setLayoutParams(new LayoutParams(
                        LayoutParams.FILL_PARENT,
                        LayoutParams.WRAP_CONTENT));
                newLL.setOrientation(LinearLayout.HORIZONTAL);
                newLL.setGravity(Gravity.LEFT);
                params = new LinearLayout.LayoutParams(LL
                        .getMeasuredWidth(), LL.getMeasuredHeight());
                newLL.addView(LL, params);
                widthSoFar = LL.getMeasuredWidth();
            } else {
                newLL.addView(LL);
            }
        }
        ll.addView(newLL);
    }
    

    注意

    我还没有测试过...我将它用于更复杂的事情并且它正在工作...您可能需要稍微调整一下。

    【讨论】:

      【解决方案4】:

      我认为你不能:(。 Android os根据字体大小计算行间距,所以'30$'使得第1行和第2行的间距变大,不知道能不能控制这个间距大小。

      要解决此问题,您可以轻松扩展 LinearLayuot 并将方向垂直放置。比放 2 个带有 fillparent 的 textviews 为宽度....

      然后实现函数,比如说 setNoGapText(String s); ,在这个函数中,您可以测量可以放在顶部 textview 中的文本(这可以使用 textutils 完成),而其余文本将适合 textview2...

      在此文本视图之间,您可以使用 padding 和 margins 属性,因此行之间的间隙看起来就像您想象的一样。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-02-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-05
        相关资源
        最近更新 更多