安卓TextView文本对齐

468

如何使 TextView 文字两端对齐(左右对齐)?

我在这里找到了一种可能的解决方案(链接),但它并不起作用(即使你将vertical-center更改为center_vertical等)。


@Jimbo 的回答对于我的情况绝对正确,在输入文本框和文本视图中,用于从右到左的阿拉伯语输入和显示。但是对于输入文本,我还必须添加 gravity="right"。 - shareef
你可以使用 https://github.com/pouriaHemmati/JustifiedTextView。 - Pouria Hemi
可以使用 https://github.com/amilcar-sr/JustifiedTextView。 - Reejesh PK
23个回答

292

我不相信Android支持全文对齐。

2018-01-01更新:Android 8.0+支持TextView的对齐模式。(参考链接)


5
进一步分析后,你可以尝试使用 android:gravity="fill_horizontal"。这被描述为“如果需要,增加对象的水平大小,使其完全填充其容器”,但我不知道他们如何“增加”文本。 - CommonsWare
8
android:gravity="fill_horizontal" 也没有起作用。看来安卓系统并不支持文本两端对齐,算了 :) - user130076
6
不,您无法像设置重力一样设置属性。但是,您仍然可以通过使用WebView而不是TextView来对文本进行对齐设置。您可以参考http://www.seal.io/2010/12/only-way-how-to-align-text-in-block-in.html。 - jcaruso
3
现在有没有合适的方法来对齐文本? - John R
1
@FarhanFarooqui:Android 8.0+ 支持对齐模式。 - CommonsWare
显示剩余7条评论

177

Android O 中的 TextView 提供了全称 (新的排版对齐) 功能。


您只需要完成以下操作:

Kotlin

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    textView.justificationMode = JUSTIFICATION_MODE_INTER_WORD
}

Java

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    textView.setJustificationMode(JUSTIFICATION_MODE_INTER_WORD);
}

XML

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:justificationMode="inter_word" />

默认值为JUSTIFICATION_MODE_NONE(在xml中为none)。


4
希望它能够被移植回支持库,O:) - Stefan Haustein
2
请在这里添加库!! - Kunal Dharaiya
5
如何证明使用 XML 是合理的? - Viks
28
你可以在xml中使用android:justificationMode="inter_word"。此设置可实现文本自动调整间距,以使每行之间的间隔更为平均,并且不会改变原意。 - Christian D
8
需要API 26或更高版本才能使用android:justificationMode。 - Bink
显示剩余10条评论

167
@CommonsWare的回答是正确的。Android 8.0+支持“全文对齐”(或简称为“对齐”)。
Android还支持“左/右对齐文本”。请参阅维基百科上有关Justification的文章以了解区别。许多人认为“对齐”的概念包括全文对齐以及左/右文本对齐,这就是他们想要进行左/右文本对齐时最终搜索的内容。此答案说明如何实现左/右文本对齐。
可以实现左/右对齐文本(而不是问题所询问的全文对齐)。为了演示,我将使用基本的两列表单(左列中的标签和右列中的文本字段)作为示例。在此示例中,左列中标签中的文本将被右对齐,以便它们紧贴其右列中的文本字段。
在XML布局中,您可以通过在所有TextView中添加以下属性来使TextView元素本身(左列)向右对齐:
<TextView
   ...
   android:layout_gravity="center_vertical|end">
   ...
</TextView>

然而,如果文本换行成多行,则文本仍将在TextView内左对齐。添加以下属性可使实际文本在TextView内右对齐(左侧不齐):
<TextView
   ...
   android:gravity="end">
   ...
</TextView>

所以gravity属性指定了如何对齐TextView内部的文本,而layout_gravity属性则指定了如何对齐/布局TextView元素本身。

13
如果我理解正确,并考虑到测试的结果,这只是将文本左对齐或右对齐。这并不使文本两端对齐,对吗? - Paul Lammertsma
15
很好。只需补充一下,如果您想要居中对齐,可以使用 android:layout_gravity="center_horizontal|center"android:gravity="center" - Luis A. Florit
对于我的情况,使用输入文本框(inputtext)和文本视图(textview),以从右到左的阿拉伯语言输入和显示,肯定能够正常工作。 - shareef
3
这只是对齐而非调整格式。请仔细阅读那个维基百科链接。不同类型的调整方式只会影响段落的最后一行。如果一个段落只有一行,就不存在左对齐/右对齐/居中对齐。 - Karu
2
如果这不是关于“justify”的问题,那么为什么要在这里回答它呢? - user924
1
这是关于左对齐或右对齐,而不是文本两端对齐(如MS Word中)。正式术语在这里并没有帮助,你理解问题的意思。 - Shuvo Sarker

141

为了在Android上调整文本的对齐方式,我使用了WebView。

    setContentView(R.layout.main);

    WebView view = new WebView(this);
    view.setVerticalScrollBarEnabled(false);

    ((LinearLayout)findViewById(R.id.inset_web_view)).addView(view);

    view.loadData(getString(R.string.hello), "text/html; charset=utf-8", "utf-8");

以及 HTML。

<string name="hello">
<![CDATA[
<html>
 <head></head>
 <body style="text-align:justify;color:gray;background-color:black;">
  Lorem ipsum dolor sit amet, consectetur 
  adipiscing elit. Nunc pellentesque, urna
  nec hendrerit pellentesque, risus massa
 </body>
</html>
]]>
</string>

我目前还不能上传图片来证明,但是“对我来说它有效”。


3
这里有一个不错的解决方案。顺便说一句,你不需要大部分额外的HTML,只需使用带有文本对齐的body标签即可。 - gnac
5
这很有效。请注意,您可以通过在view.loadData()后跟着view.setBackgroundColor("#00000000")来使背景透明。 - Paul Lammertsma
2
正如我在那些帖子中提到的,我找到了一个解决方案:如果您创建一个HTML文件并将其放置在资产中,通过view.loadUrl()加载它可以工作,而view.loadData()则不行。我不知道为什么后者不行。 - Paul Lammertsma
1
@PaulLammertsma,使用 setBackgroundColor(0x00000000) 更加正确,可以设置透明背景。 - richey
webview.loadDataWithBaseURL(null, displayString, "text/html", "utf-8", ""); - Kirit Vaghela
显示剩余3条评论

101

已更新

我们为此创建了一个简单的类。目前有两种方法可以实现您想要的效果。两种方法都不需要WEBVIEW,并且支持可扩展字符序列(SUPPORTS SPANNABLES)

https://github.com/bluejamesbond/TextJustify-Android

支持:Android 2.0到5.X

设置

// Please visit Github for latest setup instructions.

截图

Comparison.png


确实很有帮助,但使用它后,我的TextView无法保持原始格式,我指的是:边距、文本样式和我认为文本大小也不行。请继续改进它,这将会是一个非常大的帮助。 - Leonardo Sapuy
我们如何检测行末的换行符?因为有硬换行的行不应该被调整对齐。 - Mbt925
@Mbt925 我相信这个可以做到。你能发一张图片吗? - Mathew Kurian
5
感谢这个优秀的共享库,但它无法支持波斯语或阿拉伯语文本。 当我设置方向时,我的单词是从后往前绘制的,而不是从前往后。 我的意思是:我的单词是“سلام”,但是它被绘制成“مالس”。 (如果您不了解波斯语,请看这个例子:让我“1234” -> “4321”) - Naruto Uzumaki
1
基于scrollView的解决方案很好,但是还没有找到任何可以在textView中实现的答案。 :( - superUser
显示剩余10条评论

45
你可以使用在Github上的JustifiedTextView for Android项目。这是一个自定义视图,可以为您模拟对齐文本。它支持Android 2.0+和从右到左的语言。 enter image description here

它不支持可跨度字符串。 - MSepehr
我们如何添加自己的文本? - Karan
请在Github上查看示例。 - Saeed Zarinfam
嗨Saeed,谢谢你的帮助,有没有办法支持可跨度文本视图?! - Hamid Reza
@SaeedZarinfam 我尝试使用“Android的JustifiedTextView”,但在xml标签ir.noghteh.JustifiedTextView上出现错误。能否帮我解决这个问题?http://stackoverflow.com/questions/37911376/error-inflating-class-ir-noghteh-justifiedtextview - Jumong
对我来说运行良好。谢谢。 - Siamak

30

我基于本地文本视图编写了一个小部件来完成它。

Github


我推荐这个,主要是因为它基于Android官方SDK中的原始TextView,而在我个人看来,它比WebView的技术更轻量级,许多人都在发布关于这个常见话题的帖子。如果你正在构建一个需要考虑内存的应用程序,例如使用ListView对象,你可能会考虑使用类似这样的东西。我已经尝试过了,效果符合预期。如果你们知道其他更好的或者喜欢这个,请与我分享你的经验。 - superUser
很好的工作,顺便说一下。这正是我所寻找的。 - superUser
5
不支持RTL语言,如波斯语。 - fire in the hole
1
@Frank Cheng非常有用的库。我在段落末尾得到了很多空格。我该如何解决? - iSrinivasan27
1
对我来说有效,但是TextView的最后一行被截断了。我不得不将TextView的填充保持在5以下。 - TharakaNirmana
显示剩余2条评论

27

我找到了解决这个问题的方法,但这可能不是非常优雅,但效果还不错。

它的原理是将每行的空格替换为固定宽度的ImageSpan(颜色是透明的)。

public static void justify(final TextView textView) {

    final AtomicBoolean isJustify = new AtomicBoolean(false);

    final String textString = textView.getText().toString();

    final TextPaint textPaint = textView.getPaint();

    final SpannableStringBuilder builder = new SpannableStringBuilder();

    textView.post(new Runnable() {
        @Override
        public void run() {

            if (!isJustify.get()) {

                final int lineCount = textView.getLineCount();
                final int textViewWidth = textView.getWidth();

                for (int i = 0; i < lineCount; i++) {

                    int lineStart = textView.getLayout().getLineStart(i);
                    int lineEnd = textView.getLayout().getLineEnd(i);

                    String lineString = textString.substring(lineStart, lineEnd);

                    if (i == lineCount - 1) {
                        builder.append(new SpannableString(lineString));
                        break;
                    }

                    String trimSpaceText = lineString.trim();
                    String removeSpaceText = lineString.replaceAll(" ", "");

                    float removeSpaceWidth = textPaint.measureText(removeSpaceText);
                    float spaceCount = trimSpaceText.length() - removeSpaceText.length();

                    float eachSpaceWidth = (textViewWidth - removeSpaceWidth) / spaceCount;

                    SpannableString spannableString = new SpannableString(lineString);
                    for (int j = 0; j < trimSpaceText.length(); j++) {
                        char c = trimSpaceText.charAt(j);
                        if (c == ' ') {
                            Drawable drawable = new ColorDrawable(0x00ffffff);
                            drawable.setBounds(0, 0, (int) eachSpaceWidth, 0);
                            ImageSpan span = new ImageSpan(drawable);
                            spannableString.setSpan(span, j, j + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                        }
                    }

                    builder.append(spannableString);
                }

                textView.setText(builder);
                isJustify.set(true);
            }
        }
    });
}

我把代码放到了GitHub上:

https://github.com/twiceyuan/TextJustification

概述:

概述


3
在XML预览中无法工作,但在真实设备上表现很好 :) - pgreze
1
只有当 TextView 不包含任何格式时才能正常工作,不幸的是。 - richey
在Android 11中使用Kotlin工作正常。 - tanrobles

17

XML布局:声明WebView代替TextView

<WebView
 android:id="@+id/textContent"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content" />

Java代码:将文本数据设置到WebView
WebView view = (WebView) findViewById(R.id.textContent);
String text;
text = "<html><body><p align=\"justify\">";
text+= "This is the text will be justified when displayed!!!";
text+= "</p></body></html>";
view.loadData(text, "text/html", "utf-8");

这可能解决你的问题。 对我来说完全有效。


16

非常简单 我们可以在xml文件中做到这一点

<TextView 
android:justificationMode="inter_word"
/>

5
需要 API 级别 26。如何为较低级别提供支持? - viper

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接