25

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

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

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

可跨字符串是使用以下代码片段创建的:

    // 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 以使所有行具有相同的间距?

4

4 回答 4

43

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

android:lineSpacingMultiplier
android:lineSpacingExtra

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

于 2011-12-28T21:42:31.647 回答
2

经过大量的试验和错误,我得到了一个非常hacky的解决方案:

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

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

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

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

于 2014-08-08T12:55:35.060 回答
1

我写了这个函数:

输入

  • 线性布局 ll:

    将成为您的“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);
}

笔记

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

于 2011-07-29T09:44:07.410 回答
0

我认为你不能:(。Android os根据字体大小计算行之间的间隙,因此'30$'使第1行和第2行之间的间隙更大,我不知道是否可以控制这个间隙大小。

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

而不是实现功能,让我们说 setNoGapText(String s); ,在这个函数中,您可以测量可以放在顶部 textview 中的文本(这可以使用 textutils 完成),而其余的文本将适合 textview2 ...

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

于 2011-07-29T09:22:32.203 回答