Android 如何在具有多种字体大小的 TextView 中调整行高?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3046613/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to adjust line height in TextView with multiple type sizes?
提问by emmby
I have a TextView that holds a Spannable string. The string contains a bunch of text, the first word of which is double the typesize as the rest of the string.
我有一个包含 Spannable 字符串的 TextView。该字符串包含一堆文本,其中第一个单词的字体大小是字符串其余部分的两倍。
The problem is that the line spacing between the first and second line is much larger than the line spacing between subsequent lines due to the increased size of the first word.
问题是第一行和第二行之间的行距比后续行之间的行距大得多,这是由于第一个字的大小增加了。
http://img.skitch.com/20100615-fwd2aehbsgaby8s2s9psx3wwii.png
http://img.skitch.com/20100615-fwd2aehbsgaby8s2s9psx3wwii.png
The spannable string was created using the following code snippet:
spannable 字符串是使用以下代码片段创建的:
// Price
CharSequence text = " 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);
}
How can I fix my TextView so that all lines have the same spacing?
如何修复我的 TextView 以便所有行都具有相同的间距?
回答by Rangel Reale
You can try using one of these TextView properties:
您可以尝试使用以下 TextView 属性之一:
android:lineSpacingMultiplier
android:lineSpacingExtra
to at least try to make all lines the same height (same as the first one).
至少尝试使所有行具有相同的高度(与第一行相同)。
回答by miracula
After a lot of trial and error I got a very hacky solution to work:
经过大量的反复试验,我得到了一个非常hacky的解决方案:
I added spannables with the same doubled text size as the emphasized word to every space inside the text. This way the whole TextView got the same (big) line spacing. Be aware that you can not reuse a spannable.
Then I gave the TextView a negative lineSpacingExtra so the line spacing looked nice again.
To avoid unnatuarally wide spaces due to the increased text size I added a ScaleXSpan to every space, scaling them to 50% of their original big size.
我在文本内的每个空格中添加了与强调词相同的双倍文本大小的跨度。这样整个 TextView 得到了相同的(大)行距。请注意,您不能重用 spannable。
然后我给了 TextView 一个负的 lineSpacingExtra,所以行间距看起来又不错了。
为了避免由于文本大小增加而导致的不自然的宽空间,我向每个空间添加了一个 ScaleXSpan,将它们缩放到原始大尺寸的 50%。
This method should work even for TextViews that hold localized strings (where you never know at which position the emphasized word appears or how long your line will be) as long as every line holds at least one space character.
这种方法甚至适用于保存本地化字符串的 TextViews(您永远不知道强调的单词出现在哪个位置或您的行将有多长),只要每一行至少包含一个空格字符。
回答by Sherif elKhatib
I wrote this function:
我写了这个函数:
INPUT
输入
LinearLayout ll :
the Layout which will be your "TexView" (make sure its orientation is vertical)
String money:
the String you want to be different (in your case bigger textsize)
String text:
the text
Context mContext
the context
线性布局 ll :
将成为您的“TexView”的布局(确保其方向是垂直的)
串钱:
你想要不同的字符串(在你的情况下更大的文本大小)
字符串文本:
文本
上下文 mContext
上下文
WHAT TO DO
该怎么办
I commented the parts that you must edit
我评论了你必须编辑的部分
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);
}
NOTE
笔记
I have not tested it ... I used it for more complex things and it was working ... You might need to tweak a bit.
我还没有测试过它......我用它来处理更复杂的事情并且它正在工作......你可能需要稍微调整一下。
回答by Lukap
I think you can't :(. Android os calculate the gaps between the lines according the font size, so that '30$' makes gap between line 1 and line 2 to be bigger, and I do not know if it is possible to control this gap size.
我认为你不能:(。Android os 根据字体大小计算行之间的差距,因此 '30$' 使第 1 行和第 2 行之间的差距更大,我不知道是否可以控制这个间隙大小。
To solve this you can easily extend LinearLayuot and put the orientation vertical. Than put 2 textviews with fillparent for width....
为了解决这个问题,您可以轻松扩展 LinearLayuot 并将方向垂直放置。比将 2 个 textviews 与 fillparent 放在一起作为宽度....
and than implement function , let say setNoGapText(String s); , and in this function you can measure the text that can be fit in the textview on the top(this can me done with textutils), and than the rest of the text will be fit on textview2...
然后实现函数,比如说 setNoGapText(String s); ,并且在此功能中,您可以测量适合顶部 textview 的文本(这可以使用 textutils 完成),而其余文本将适合 textview2 ...
between this textview you can play with padding and margins properties so the gaps between lines will look just like you imagine them.
在此文本视图之间,您可以使用 padding 和 margins 属性,因此行之间的间隙看起来就像您想象的那样。