Java 使android textview的某个部分向右对齐
我有这个Java 使android textview的某个部分向右对齐,java,android,android-widget,Java,Android,Android Widget,我有这个TextView。它的一些部分应该向左对齐,一些部分应该向右对齐。在Java中如何实现这一点 基本上,我希望第一行向左对齐,下一行向右对齐,依此类推 有人有线索吗 编辑 我曾经尝试过使用HTML,但当它不起作用时,我尝试了使用spans html尝试 textView.setText(Html.fromHtml("<p align=\"right\">THIS IS TO THE RIGHT</p>")); 但它们似乎都不起作用。两种解决方案: 1) 为每一行设
TextView
。它的一些部分应该向左对齐,一些部分应该向右对齐。在Java中如何实现这一点
基本上,我希望第一行向左对齐,下一行向右对齐,依此类推
有人有线索吗
编辑
我曾经尝试过使用HTML,但当它不起作用时,我尝试了使用spans
html尝试
textView.setText(Html.fromHtml("<p align=\"right\">THIS IS TO THE RIGHT</p>"));
但它们似乎都不起作用。两种解决方案:
1) 为每一行设置不同的文本视图并设置其重力
2) 加载数据时使用Html为其设置Html对齐方式
这不起作用
编辑:
也
3:将使用span.简单。在textview中调整xml部分。使用布局。如果您希望文本视图位于左侧 android:alignParentLeft=“true”有关align的更多详细信息,请参见此 这也是不同布局的一个例子
Alignment.ALIGN\u相反的是右侧的等效项。
Alignment.ALIGN\u NORMAL等同于left side。
这里有一个与Spannable一起工作的解决方案,如果右侧和左侧太宽,它们将在同一条线上重叠。由于使用spannable执行左/右技巧需要在左和右之间添加换行符,因此我的解决方案是添加一个spannable,将换行符的换行符高度降低为零(即重叠行),然后恢复正常的换行符高度
String fullText = leftText + "\n " + rightText; // only works if linefeed between them! "\n ";
int fullTextLength = fullText.length();
int leftEnd = leftText.length();
int rightTextLength = rightText.length();
final SpannableString s = new SpannableString(fullText);
AlignmentSpan alignmentSpan = new AlignmentSpan.Standard(Layout.Alignment.ALIGN_OPPOSITE);
s.setSpan(alignmentSpan, leftEnd, fullTextLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
s.setSpan(new SetLineOverlap(true), 1, fullTextLength-2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
s.setSpan(new SetLineOverlap(false), fullTextLength-1, fullTextLength, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
我们有处理重叠线的小程序:
private static class SetLineOverlap implements LineHeightSpan {
private int originalBottom = 15; // init value ignored
private int originalDescent = 13; // init value ignored
private Boolean overlap; // saved state
private Boolean overlapSaved = false; // ensure saved values only happen once
SetLineOverlap(Boolean overlap) {
this.overlap = overlap;
}
@Override
public void chooseHeight(CharSequence text, int start, int end, int spanstartv, int v,
Paint.FontMetricsInt fm) {
if (overlap) {
if (!overlapSaved) {
originalBottom = fm.bottom;
originalDescent = fm.descent;
overlapSaved = true;
}
fm.bottom += fm.top;
fm.descent += fm.top;
} else {
// restore saved values
fm.bottom = originalBottom;
fm.descent = originalDescent;
overlapSaved = false;
}
}
}
谢谢你的提示,@Frank,但这已经足够了:
public class LineOverlapSpan implements LineHeightSpan {
@Override
public void chooseHeight(final CharSequence text, final int start, final int end, final int spanstartv, final int v, final Paint.FontMetricsInt fm) {
fm.bottom += fm.top;
fm.descent += fm.top;
}
}
这样使用:
CharSequence text = return new Truss()
.append("LEFT")
.pushSpan(LineOverlapSpan())
.append("\n")
.popSpan()
.pushSpan(AlignmentSpan.Standard(Layout.Alignment.ALIGN_OPPOSITE))
.append("RIGHT")
.build()
其中Truss
为
一个SpannableStringBuilder
包装器,它的API不会让我觉得刺眼
- 杰克·沃顿
启发了其他解决方案,但解决了多行文本问题和文本重叠问题
class LineOverlapSpan() : LineHeightSpan {
var originalBottom: Int = 0
var originalDescent: Int = 0
var overlapSaved = false
override fun chooseHeight(
text: CharSequence?,
start: Int,
end: Int,
spanstartv: Int,
v: Int,
fm: Paint.FontMetricsInt?
) {
if (fm == null) {
return
}
if (!overlapSaved) {
originalBottom = fm.bottom
originalDescent = fm.descent
overlapSaved = true
}
if (text?.subSequence(start, end)?.endsWith("\n") == true) {
fm.bottom += fm.top
fm.descent += fm.top
} else {
fm.bottom = originalBottom
fm.descent = originalDescent
}
}
}
用法:
fun keyValueSpan(key: CharSequence, value: CharSequence) = span {
span {
alignment = "normal"
+key
span {
textColor = Color.TRANSPARENT
+value
}
span {
+"\n"
addSpan(LineOverlapSpan())
}
}
span {
alignment = "opposite"
+value
}
}
Kotlin的解决方案是使用Kpan库嗯,我认为第二个使用HTML的解决方案是一个很好的方法,但它不起作用。。textView.setText(Html.fromHtml(“这应该在右边”);textView.setText(Html.fromHtml(“这应该在右边”);你确定html中的对齐方式也适用于textview吗?我刚刚尝试了一些示例,并研究了html不支持对齐方式是的,我也读了。。但为什么span解决方案不起作用。。这应该行得通,不是吗?嗯,它不对。textview中的重力重要吗?@user1991905
textview的重力在这里很重要。尽量不要在xml中提供android:gravity
内部TextView
。这只适用于我,如果我使用整行的span,而不是一部分:(@WonderCsaboAlignmentSpan.Standard
是一种段落样式,因此您需要在LeftText
(即.\n)中添加一个新行字符以使RightText
右对齐。(我没有测试上面的特定示例)对于我来说,我只能让它与换行符“\n”一起使用而不是两个空格,并将setSpan的第二个参数设置为LeftText.length(),不带“+2”。我尝试了许多组合,试图消除我不想要的换行符,但没有找到令人满意的解决方案。这是一个很好的技巧,但如果在textview中LeftText超过1行(不带换行符),则不起作用
class LineOverlapSpan() : LineHeightSpan {
var originalBottom: Int = 0
var originalDescent: Int = 0
var overlapSaved = false
override fun chooseHeight(
text: CharSequence?,
start: Int,
end: Int,
spanstartv: Int,
v: Int,
fm: Paint.FontMetricsInt?
) {
if (fm == null) {
return
}
if (!overlapSaved) {
originalBottom = fm.bottom
originalDescent = fm.descent
overlapSaved = true
}
if (text?.subSequence(start, end)?.endsWith("\n") == true) {
fm.bottom += fm.top
fm.descent += fm.top
} else {
fm.bottom = originalBottom
fm.descent = originalDescent
}
}
}
fun keyValueSpan(key: CharSequence, value: CharSequence) = span {
span {
alignment = "normal"
+key
span {
textColor = Color.TRANSPARENT
+value
}
span {
+"\n"
addSpan(LineOverlapSpan())
}
}
span {
alignment = "opposite"
+value
}
}