android - RecyclerView 中带有 ImageSpans 的 TextView = 布局错误

标签 android android-layout textview spannablestring imagespan

我在 TextView 中插入 ImageSpans,它是 RecyclerView 的一部分。大多数情况下它工作正常,但当您上下滚动时,有时 TextView 高度错误,原因不明 - 垂直空白过多。

在特定设备上的此布局中,具有 1 行文本的 TextView 的正确高度是 48,错误的高度是 80(我从 HierarchyViewer 获得这些值)。有趣的是,包含 ImageSpan 的 1 行文本的 TextView 的正确高度是 80。图片跨度)。

此屏幕截图将“Anore”和“Halal blahs”TextView 显示为 80 像素高,这是错误的。 “Hello”TextView 在 48 像素处是正确的。

Wrong height (80)

在调查这个问题时,我打开了 DDMS 并运行了“Dump UI hierarchy”,然后发生了一些有趣的事情:TextView 的高度在运行中自行修正:

Correct height (48)

这是非常有说服力的证据,表明问题是在更新文本后 TextView 的布局不正确,所以我尝试了各种方法来调用 TextView 及其父 View 上的 forceLayout() 和 invalidate(),但它没有帮助。

我尝试用 ListView 替换 RecyclerView,但没有成功。我尝试让所有 ImageSpans 使用相同的可绘制对象,但没有成功。

我运行了 HierarchyViewer,但它没有像 UI Automator 那样“修复”布局。甚至当我按下“无效布局”和“请求布局”按钮时也没有。

我没有做任何花哨的设置 ImageSpans:

SpannableStringBuilder stringBuilder = new SpannableStringBuilder( rawText );
for( int i = inlineImages.size() - 1; i >= 0; i-- ) {
    InlineImage img = inlineImages.get( i );
    stringBuilder.insert( img.idx, "x" );
    ImageSpan span = new ImageSpan( context, img.drawable );
    stringBuilder.setSpan( span, img.idx, img.idx + 1, 0 );
}

holder.mText.setText( stringBuilder );

// none of this helps
holder.mText.forceLayout();
holder.mText.requestLayout();
holder.mText.invalidate();

这是每个列表项的布局的相关部分:

<?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">

    <LinearLayout
        android:id="@+id/speech_bubble"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:background="@drawable/speech_bubble_right"
        android:layout_marginLeft="40dp"
        >

        <TextView
            android:id="@+id/text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:layout_toRightOf="@id/timestamp"
            />

    </LinearLayout>

</RelativeLayout>

我尝试使 TextView 父级 (LinearLayout) 上的布局失效并强制布局,但它什么也没做。

我试着将布局编辑成这样:

<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/text"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceMedium"
    />

.. 问题仍然存在。肯定是TextView本身的问题。

最佳答案

我猜这里的问题不在于 TextView 的测量,而是 TextView 容器的测量(一些 ViewGroup - 也许是线性布局?).

如果此 ViewGroup 的布局参数针对高度设置为 WRAP_CONTENT,则出于某种原因,高度不会按时再次计算。要解决此问题,请尝试以下操作:

int widthMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY);
int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
holder.mContainer.measure(widthMeasureSpec, heightMeasureSpec); // perhaps a simple call to requestLayout or forceLayout will be enough?

如果您知道单元格的确切高度,您也可以使用它 - 只需将我计算 heightMeasureSpec 的行替换为以下内容:

int heightMeasureSpec = MeasureSpec.makeMeasureSpec(calculatedHeight + topPadding + bottomPadding, MeasureSpec.EXACTLY);

希望这对您有所帮助。

关于android - RecyclerView 中带有 ImageSpans 的 TextView = 布局错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29045059/

相关文章:

android - Android 2.3 中性能问题的内部连接顺序

java - 如何在 Android 库模块中使用振动器

android - 如何将 RelativeLayout 的宽度设置为与兄弟 View 相同?

ios - 在ios objective c中单击按钮动态添加textview

Android Oreo 字体系列 NPE 崩溃

ios - 在返回键上以及在文本字段/ TextView 之外按下时关闭键盘

java - Java中如何从字符串中提取url?

java - 在类中使用 findViewById 时出现问题

java - 错误的 xml block 3 线性布局和 2 日历

android - 在 ScrollView android 中自由拖动 View