如果你有一个带有layout_width="wrap_content"
的TextView并且它必须换行到第二行以包含文本,那么它将调整其宽度以用尽所有可用空间(尊重边距等)。但为什么在视图的末尾有填充?我刚把它告诉 wrap_content ,所以它应该包装那些内容!这似乎是一个错误,这在股票Messenger应用程序的聊天UI中可见。 (图像来自我自己的应用程序。但是额外的空间肯定是而不是在9补丁中。)
任何解决方法?
更新:响应者/评论者错过了这一点。也许我上传的图片具有误导性,因为它是从我的应用程序设计的。任何TextView都会出现问题,您可以通过样式化视图边界将不再紧密的背景来查看。我上传了一张不同的图片。以下是图像中TextViews的XML:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="20dp"
android:layout_marginStart="20dp"
android:background="#dddddd"
android:text="This doesn't wrap"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:layout_gravity="center_horizontal"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="20dp"
android:layout_marginStart="20dp"
android:layout_gravity="center_horizontal"
android:background="#dddddd"
android:text="This wraps and look, the bounds does not fit tight against the right edge of text"
/>
答案 0 :(得分:4)
首先,在看到你的帖子时,我认为问题是因为标准的Android TextView在其基本风格中定义了一些默认填充。如果想要删除它,可以尝试类似:
android:paddingRight="0dp"
或
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int specModeW = MeasureSpec.getMode(widthMeasureSpec);
if (specModeW != MeasureSpec.EXACTLY) {
Layout layout = getLayout();
int linesCount = layout.getLineCount();
if (linesCount > 1) {
float textRealMaxWidth = 0;
for (int n = 0; n < linesCount; ++n) {
textRealMaxWidth = Math.max(textRealMaxWidth, layout.getLineWidth(n));
}
int w = (int) Math.ceil(textRealMaxWidth);
if (w < getMeasuredWidth()) {
super.onMeasure(MeasureSpec.makeMeasureSpec(w, MeasureSpec.AT_MOST),
heightMeasureSpec);
}
}
}
}
由于您的帖子已更新,我了解您的问题不是来自填充,而是来自自动换行。实际上,当要显示多行时,Android TextView会使用宽度上的整个可用空间。
如上所述in this post,没有标准解决方案,您需要自定义文本视图以在填充后修复其宽度。
覆盖你的textView的onMeasure方法,如下面的shoud work(灵感来自“天空”答案):
Like below: @Override
public Intent onBuildStartFragmentIntent (String fragmentName,
Bundle args,
int titleRes,
int shortTitleRes)
{
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setClass(this, getClass());
intent.putExtra(EXTRA_SHOW_FRAGMENT, fragmentName);
intent.putExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS, args);
intent.putExtra(EXTRA_SHOW_FRAGMENT_TITLE, titleRes);
intent.putExtra(EXTRA_SHOW_FRAGMENT_SHORT_TITLE, shortTitleRes);
intent.putExtra(EXTRA_NO_HEADERS, true);
intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);//the new statement
return intent;
}
答案 1 :(得分:4)
我发现所选答案很有帮助,虽然它没有完全考虑填充。我将选定的答案与this post's answer结合起来,得出一个适用于填充的视图。仅供参考,另一篇文章的回答有一个缺陷,即视图有时会在几个像素处被切断。
public class TightTextView extends TextView {
public TightTextView(Context context) {
super(context);
}
public TightTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public TightTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int specModeW = MeasureSpec.getMode(widthMeasureSpec);
if (specModeW != MeasureSpec.EXACTLY) {
Layout layout = getLayout();
if (layout != null) {
int w = (int) Math.ceil(getMaxLineWidth(layout)) + getCompoundPaddingLeft() + getCompoundPaddingRight();
if (w < getMeasuredWidth()) {
super.onMeasure(MeasureSpec.makeMeasureSpec(w, MeasureSpec.AT_MOST),
heightMeasureSpec);
}
}
}
}
private float getMaxLineWidth(Layout layout) {
float max_width = 0.0f;
int lines = layout.getLineCount();
for (int i = 0; i < lines; i++) {
if (layout.getLineWidth(i) > max_width) {
max_width = layout.getLineWidth(i);
}
}
return max_width;
}
}
答案 2 :(得分:0)
很确定这是因为&#34;反对&#34;不适合单词&#34; fit&#34;和右边缘。如果您想对此进行测试,请尝试将文本更改为一堆|,并在每个文本之间留出一个空格。
答案 3 :(得分:0)
我最近在为应用程序开发聊天气泡视图时遇到了类似的问题,因此我使用了公认的解决方案中的想法以及@hoffware的改进,然后在Kotlin中重新实现了它们。
import android.content.Context
import android.util.AttributeSet
import android.view.View.MeasureSpec.*
import androidx.appcompat.widget.AppCompatTextView
import kotlin.math.ceil
class TightTextView
@JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = android.R.attr.textViewStyle
) : AppCompatTextView(context, attrs, defStyleAttr) {
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
val lineCount = layout.lineCount
if (lineCount > 1 && getMode(widthMeasureSpec) != EXACTLY) {
val textWidth = (0 until lineCount).maxOf(layout::getLineWidth)
val padding = compoundPaddingLeft + compoundPaddingRight
val w = ceil(textWidth).toInt() + padding
if (w < measuredWidth) {
val newWidthMeasureSpec = makeMeasureSpec(w, AT_MOST)
super.onMeasure(newWidthMeasureSpec, heightMeasureSpec)
}
}
}
}