Android: 文本视图的最后一行被切断

我有一个水平 LinearLayout包含一个 TextView后面跟着一个 Spinner旁边。该 LinearLayout在包含在 RelativeLayout中的固定垂直 LinearLayout中动态充气多次。

问题是,因为我从 Theme.light切换到 Theme.holo.lightTextView的最后一行被切成两半。当动态文本很长并且跨越多行时,就会发生这种情况。

enter image description here

我已经能够通过添加底部填充到包含 TextViewSpinner的水平 LinearLayout来解决这个问题。

这不像是一个修复,而更像是一个黑客。有没有人能给我一些关于如何正确解决这个问题的建议?

我也读了一些其他的问题,但似乎没有帮助。

横向线性布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">


<TextView
android:id="@+id/textView1"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_marginRight="20dp"
android:text="TextView"/>


<Spinner
android:id="@+id/spinner1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>


</LinearLayout>

相对布局,上面的布局在线性布局动态膨胀,id ll2 _ 7:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >


<ScrollView
android:id="@+id/scrollView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/relLayoutButtonNext"
android:layout_below="@id/textView1" >


<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingBottom="20dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="10dp" >


<TextView
android:id="@+id/textView10"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="30dp"
android:text="2.7" />


<TextView
android:id="@+id/textView11"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_toRightOf="@id/textView10"
android:text="@string/question2_7" />




<LinearLayout
android:id="@+id/ll2_7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textView11"
android:layout_below="@+id/textView11"
android:orientation="vertical" android:layout_marginBottom="20dp">
</LinearLayout>


</RelativeLayout>


</ScrollView>


</RelativeLayout>

编辑: 下面是上面的完整布局 xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >


<TextView
android:id="@+id/textView1"
style="@style/question_section_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="@string/question2_header" />


<RelativeLayout
android:id="@+id/relLayoutButtonNext"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@color/bottomBar"
android:paddingBottom="3dp"
android:paddingLeft="50dp"
android:paddingRight="50dp"
android:paddingTop="3dp" >


<Button
android:id="@+id/buttonNext"
android:layout_width="180dp"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:onClick="nextStep"
android:text="Next Section"
android:textSize="20sp" />


<Button
android:id="@+id/buttonPrevious"
android:layout_width="180dp"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:onClick="previousStep"
android:text="Previous Section"
android:textSize="20sp" />
</RelativeLayout>




<ScrollView
android:id="@+id/scrollView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/relLayoutButtonNext"
android:layout_below="@id/textView1" >






<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingBottom="20dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="10dp" >


<TextView
android:id="@+id/textView10"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="30dp"
android:text="2.7" />


<TextView
android:id="@+id/textView11"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_toRightOf="@id/textView10"
android:text="@string/question2_7" />




<LinearLayout
android:id="@+id/ll2_7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textView11"
android:layout_below="@+id/textView11"
android:orientation="vertical" android:layout_marginBottom="20dp">


</LinearLayout>


<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textView10"
android:layout_below="@+id/ll2_7"
android:text="2.8" />


<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/ll2_7"
android:layout_toRightOf="@+id/textView10"
android:text="@string/question2_8" android:layout_marginBottom="10dp"/>




<LinearLayout
android:id="@+id/ll2_8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textView3"
android:layout_below="@+id/textView3"
android:layout_marginBottom="20dp"
android:orientation="vertical" >


</LinearLayout>


<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textView2"
android:layout_below="@+id/ll2_8"
android:text="2.9" />


<TextView
android:id="@+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/ll2_8"
android:layout_toRightOf="@+id/textView10"
android:text="@string/question2_9" android:layout_marginBottom="10dp"/>




<LinearLayout
android:id="@+id/ll2_9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/textView5"
android:layout_toRightOf="@+id/textView10"
android:orientation="vertical" android:layout_marginBottom="20dp">


</LinearLayout>


<TextView
android:id="@+id/textView6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textView4"
android:layout_below="@+id/ll2_9"
android:text="2.10" />


<TextView
android:id="@+id/textView7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/ll2_9"
android:layout_toRightOf="@+id/textView10"
android:text="@string/question2_10" android:layout_marginBottom="10dp"/>




<LinearLayout
android:id="@+id/ll2_10"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/textView7"
android:layout_marginBottom="20dp"
android:layout_toRightOf="@+id/textView10"
android:orientation="vertical" >


</LinearLayout>


<TextView
android:id="@+id/textView8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textView6"
android:layout_below="@+id/ll2_10"
android:text="2.11" />


<TextView
android:id="@+id/textView9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/ll2_10"
android:layout_toRightOf="@+id/textView10"
android:text="@string/quesiton2_11" android:layout_marginBottom="10dp"/>




<LinearLayout
android:id="@+id/ll2_11"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textView9"
android:layout_below="@+id/textView9"
android:orientation="vertical" android:layout_marginBottom="20dp">


</LinearLayout>


<TextView
android:id="@+id/textView12"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textView8"
android:layout_below="@+id/ll2_11"
android:text="2.11.1" />


<TextView
android:id="@+id/textView13"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/ll2_11"
android:layout_toRightOf="@+id/textView10"
android:text="@string/question2_11_1" android:layout_marginBottom="10dp"/>




<LinearLayout
android:id="@+id/ll2_11_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/textView13"
android:layout_toRightOf="@+id/textView10"
android:orientation="vertical" android:layout_marginBottom="20dp">


</LinearLayout>


</RelativeLayout>


</ScrollView>


</RelativeLayout>
85702 次浏览

尝试删除 android: paddingBottom = “20dp”

来自

 <RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingBottom="20dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="10dp" >

在尝试了一百万种不同的方法之后,我想我找到了答案。

我对 TextView 项应用了 LayoutGravity:

android:layout_gravity="fill"

似乎解决了我所有的剪辑问题。希望这对有同样问题的人有所帮助。

我也有同样的问题,而且很烦人。

只有阿拉伯文才会这样。

如果你让标签多行,并在字符串末尾添加一个 \n,它会修复它,但问题是这个标签和下面的对象之间会有一个很大的差距,因为这个字段现在有一个新的空行在它的下面。

可以通过自定义控件来解决这个问题,但总的来说,这是一个恼人的错误。

如果你有这个问题,你的 TextView是在一个 RelativeLayout,尝试切换到一个 LinearLayoutRelativeLayout

解决了我的问题

当这种情况发生时,您应该确保 TextView不会比它的容器增大-

如果一个 TextView被设置为 wrap_content,并且它的容器(或者一个祖先的容器)没有为 TextView的生长留出空间,那么它可以被阻塞。

如果不是这样的话,也有可能 TextViewonMeasure()有时不能正确地测量字母的尾部,非拉丁字符或者因为文本是斜体而产生的效果。你可以通过为你的 TextView设置一个全局样式来纠正这个问题,这样它就不需要改变你的整个代码库就可以被识别出来:

Ensure that you're application/activities use a custom theme like so:

<style name="Custom" parent="@android:style/Theme.Light">
<item name="android:textViewStyle">@style/Custom.Widget.TextView</item>
</style>


<style name="Custom.Widget.TextView" parent="@android:style/Widget.TextView">
<item name="android:gravity">fill</item>
<item name="android:padding">1sp</item>
</style>

The answer by @Rynadt was really helpful in getting to the above stage. Setting the gravity of the Text inside the View ensures on some devices that occlusion never takes place (The text is correctly fitted inside the view), on others a helping hand with padding of an sp value, ensures that the tails et al are accounted for with a TextSize specific value.

我遇到了与截图中相同的截止问题。它是由水平 LinearLayout的基线对齐引起的。由于字体大小不同,TextViewSpinner的基准线不同。为了解决这个问题,需要通过设置:

android:baselineAligned="false"

或在代码中:

layout.setBaselineAligned(false);

Best workaround for this is to add a dummy View of desired height (i.e. this will add padding itself) at the bottom of your view.

<TableRow
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp" >
<View
android:layout_width="match_parent"
android:layout_height="30dp"/>
</TableRow>

就像在我的例子中,我在视图的底部添加了一个表行。希望这个能帮到别人。

我在文本后面添加了一些虚拟空间

textView.setText(firstString+"\n");

我尝试了所有其他的解决方案,但这是唯一适合我的解决方案

我通过扩展 TextView 并添加这样的自定义 Class 找到了一个不同的解决方案:

 public class AdaptingTextView extends TextView {


public AdaptingTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}


public AdaptingTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}


public AdaptingTextView(Context context) {
super(context);
}


@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);


// set fitting lines to prevent cut text
int fittingLines = h / this.getLineHeight();
if (fittingLines > 0) {
this.setLines(fittingLines);
}
}


}

我也有同样的问题,发现简单地加上

android:includeFontPadding="false"

最后一行文字的下行部分不再被剪裁。

I finally fixed it!

我尝试添加字符串到 TextView在职人士,然后调用 scrollTo () ,最后一行被切断!

ScrollTo ()应该在“ Runnable”中调用,比如:

private ScrollView mScrollView;
public void scrollToBottom()
{
mScrollView = (ScrollView) findViewById(R.id.debug_textview_scrollview);
mScrollView.post(new Runnable()
{
public void run()
{
mScrollView.fullScroll(View.FOCUS_DOWN);
}
});
}

我认为这是因为在调用 scrollTo ()服务的时刻,TextView 的更新还没有准备好。

我的解决方案接近公认的解决方案,但我不得不改变它

   android:layout_gravity="fill_vertical"

取而代之。否则,其他行也会被拉长,并在随机的位置添加换行符。例如,最大的一行有4行,因此另一行从

this is a testphrase

to

thi
s is
a testph
rase

You can use a global layout listener for a TextView in any type of ViewGroup.

    final TextView dSTextView = (TextView)findViewById(R.id.annoyingTextView);
dSTextView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {


@Override
public void onGlobalLayout() {
dSTextView.getViewTreeObserver().removeOnGlobalLayoutListener(this);


float lineHeight = dSTextView.getLineHeight();
int maxLines = (int) (dSTextView.getHeight() / lineHeight);


if (dSTextView.getLineCount() != maxLines) {
dSTextView.setLines(maxLines);
}


}
});

你可以阅读更多关于它的资料

我认为通过改变布局,你能做的很少。因为我发现有些方法只在某些情况下有效。我认为这取决于整个布局层次结构,而不是一个放之四海而皆准的解决方案。我还注意到,特别是当你有一个不同的字体,你想设置到 TextView。

我已经试验和测试过的一个可靠的快照方法是,可以在视图膨胀之后在代码中设置 font 属性。我假设您在资产/字体文件夹中有您想要的字体。

例如:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_view, container, false);
TextView tv = (TextView)view.findViewById(R.id.text_view);
tv.setText("Insert text that needs to be displayed");
AssetManager assetManager = getContext().getAssets();
Typeface typeFace = Typeface.createFromAsset(assetManager, "Fonts/OpenSans-Light.ttf");
tv.setTypeface(typeFace , 0); // 0 is normal font
tv.setPadding(10,  0, 10, 0); // This is not mandatory
}

在一个活动中:

@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(Resource.Layout.main_activity);
TextView tv = (TextView)this.findViewById(R.id.text_view);
tv.setText("Insert text that needs to be displayed");
AssetManager assetManager = getContext().getAssets();
Typeface typeFace = Typeface.createFromAsset(assetManager, "Fonts/OpenSans-Light.ttf");
tv.setTypeface(typeFace , 0); // 0 is normal font
tv.setPadding(10,  0, 10, 0); // This is not mandatory
}

getViewTreeObserver().addOnGlobalLayoutListener在回收者视图中不起作用。如果你正在使用回收者,使用 View.addOnLayoutChangeListener:

我发现在 xml 中为 textView定义的省略号并不总是被反映出来,所以我在重新分配 text 属性之前以编程方式设置它。这招对我很管用。

textView.addOnLayoutChangeListener(new OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom,
int oldLeft, int oldTop, int oldRight, int oldBottom) {
textView.removeOnLayoutChangeListener(this);
float lineHeight = textView.getLineHeight();
int maxLines = (int) (textView.getHeight() / lineHeight);
if (textView.getLineCount() != maxLines) {
textView.setLines(maxLines);
textView.setEllipsize(TextUtils.TruncateAt.END);
// Re-assign text to ensure ellipsize is performed correctly.
textView.setText(model.getText());
}
}
});

我知道现在很晚了,但这份工作对我来说很有吸引力。 将此代码添加到 textview

android:ellipsize="marquee"
android:layout_weight="1"

将有问题的文本视图放入框架布局中。我认为文本视图计算不正确是因为兄弟视图 Spinner。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">


<FrameLayout
android:layout_width="150dp"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textView1"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_marginRight="20dp"
android:text="TextView"/>
</FrameLayout>
<Spinner
android:id="@+id/spinner1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>

在文本视图的底部添加空白:

android:paddingBottom="24dp"

我遇到了同样的问题,并找到了一个方便的解决办法。我得到渲染后 TextView 的行数,并根据行数设置高度。这是密码。

TextView textView = (TextView) layout.findViewById(R.id.textView);
textView.setText(this.text);
textView.post(new Runnable() {
@Override
public void run() {
int linesCount = textView.getLineCount();
textView.setLines(linesCount);
}
});

对我来说,这个解决方案非常有效。

最外层布局的高度和宽度是动态设置的,因此即使我在 xml 中设置 android: maxLines (对于不同的设备,它的行为也是不同的) ,其中包含的 TextView 也会得到文本剪切。

在尝试了不同的方法之后,我终于找到了解决问题的办法。

Textview:

public class CustomTextView extends androidx.appcompat.widget.AppCompatTextView {
public CustomTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public CustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomTextView(Context context) {
super(context);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
// set fitting lines to prevent cut text
int fittingLines = h / this.getLineHeight();
if (fittingLines > 0) {
this.setLines(fittingLines);
this.setEllipsize(TextUtils.TruncateAt.END);
}
}
}

Xml:

<com.myproject.android.customviews.CustomTextView
android:id="@+id/tv_partner_description"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="top"
android:textColor="@color/white"
android:textSize="@dimen/text_small_medium" />

为特定的语言创建主题,比如 style-ar,截断文本视图:

<style name="EnnodaCustomTextView" parent="Widget.AppCompat.TextView">
<item name="android:paddingTop">1dp</item>
<item name="android:paddingBottom">1dp</item>
</style>

在你的 AppTheme 中应用它来反映整个应用程序的底部填充,如下所示:

    <item name="android:textViewStyle">@style/EnnodaCustomTextView</item>

Note : create same style name in default styles.xml with no item tags for padding..(where no need of extra padding )