我在硬件加速活动 ( 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
.
为了解决这个问题,我写了一些代码在文本太长时禁用视图上的硬件加速:
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 变为 invisible。如果我尝试使用LAYER_TYPE_HARDWARE
. (我尝试过,因为硬件加速指南说将图层类型设置为硬件以用于具有 alpha 的大视图。)
另外,我确实尝试过永久设置视图层类型。两种类型的结果略有不同:
LAYER_TYPE_SOFTWARE
:当使用小于限制的文本创建活动时,它呈现良好。当添加文本超过限制时,视图会消失。当文本再次缩短到限制范围内时,它会重新出现。LAYER_TYPE_HARDWARE
:LAYER_TYPE_SOFTWARE
与文本在太长后缩短时不会重新出现不同之外相同。必须重新创建活动才能使文本重新出现。
TL;博士
我遇到了由 OpenGL 限制引起的视图渲染问题,但view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
正在使视图消失而不是解决问题。