【问题标题】:TextView with long text invisible with LAYER_TYPE_HARDWARE or LAYER_TYPE_SOFTWARE带有长文本的 TextView 使用 LAYER_TYPE_HARDWARE 或 LAYER_TYPE_SOFTWARE 不可见
【发布时间】:2013-06-06 03:33:22
【问题描述】:

我在硬件加速活动 (android:hardwareAccelerated="true") 中呈现长 TextView 时遇到问题。 textview 没有背景颜色(即它是透明的)。当文本超过一定长度时,textview 会以纯黑色背景而不是透明背景呈现。

TextView 中的文本可以由用户编辑,并且被强制不换行,除非在实际换行处。我通过这样计算文本的宽度来做到这一点:

int textWidth = 0;
String[] lines = string.split("\\n");
for (String line : lines) {
    int lineWidth = (int) tv.getPaint().measureText(line);
    if (lineWidth > textWidth) {
        textWidth = lineWidth;
    }
}
int width = m.getPaddingLeft() + tv.getPaddingLeft() + textWidth
            + tv.getPaddingRight() + m.getPaddingRight();

然后我重写 ViewGroup 的 onMeasure 方法,强制宽度至少和文本一样长:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    int newWidth = Math.max(getMeasuredWidth(), width);
    setMeasuredDimension(newWidth, getMeasuredHeight());
}

所有这些都按预期工作,但它允许文本变得非常大 - 显然太大了。

尝试的解决方案: 我猜测问题出在 OpenGL 无法渲染那么长的东西,所以我查询了GL_MAX_TEXTURE_SIZE OpenGL 参数并将其与width 进行了比较。果然是width > GL_MAX_TEXTURE_SIZE时出现问题。

为了解决这个问题,我给disable hardware acceleration on the view写了一些代码,当文字太长时:

int[] maxGlTexSize = new int[1];
GLES20.glGetIntegerv(GLES20.GL_MAX_TEXTURE_SIZE, maxGlTexSize, 0);
if (width > maxGlTexSize[0]) {
    Log.e("Debug", "Too big for GL");
    tv.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
} else {
    Log.i("Debug", "Small enough for GL");
    tv.setLayerType(View.LAYER_TYPE_NONE, null);
}

但是,此代码对我不起作用。当满足条件时(文本太长),textview 变得不可见。如果我尝试使用LAYER_TYPE_HARDWARE,也会发生这种情况。 (我尝试这样做是因为the Hardware Acceleration guide 说将图层类型设置为 HARDWARE 以用于具有 alpha 的大视图。)

另外,我确实尝试过永久设置视图层类型。两种类型的结果略有不同:

  • LAYER_TYPE_SOFTWARE:当使用小于限制的文本创建活动时,它呈现良好。当添加文本超过限制时,视图消失。当文本再次缩短到限制范围内时,它会重新出现。

  • LAYER_TYPE_HARDWARE:与LAYER_TYPE_SOFTWARE 相同,只是文本在太长后缩短时不会重新出现。必须重新创建活动才能使文本重新出现。

TL;DR

我遇到了由 OpenGL 限制引起的视图渲染问题,但 view.setLayerType(View.LAYER_TYPE_SOFTWARE, null); 正在使视图消失而不是解决问题。

【问题讨论】:

    标签: android view textview android-ui hardware-acceleration


    【解决方案1】:

    在考虑了这个问题之后,我意识到改变视图的图层类型并不能解决问题是有道理的。如果 Activity 是硬件加速的,那么无论视图是否是硬件加速,视图仍然必须存储在 GPU 纹理中才能呈现到屏幕上。

    为了解决这个问题,我只是降低了文本的分辨率(大小),直到视图的宽度小于GL_MAX_TEXTURE_SIZE。这很有效,因为如果用户显示大量文本,则文本不需要高分辨率,因为他们会将其缩小以适应屏幕上的所有文本。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-30
      • 2021-06-26
      • 2018-11-15
      • 1970-01-01
      • 2016-04-13
      • 2011-02-07
      • 2013-07-06
      • 1970-01-01
      相关资源
      最近更新 更多