自定义ImageView在recycleView中一出屏就失去透明度
Custom ImageView loses transparency as soon as it goes out of screen in recycleView
我有一个自定义 ImageView,它覆盖 onDraw 方法以使用 Path 裁剪角以给出给定半径的圆角。我有一个 RecyclerView,我在所有 4 个项目中都有这些自定义 ImageView。现在的问题是这个自定义 ImageView 首次出现在列表中时呈现良好。一次只能容纳 2 个屏幕。当我向下滚动时,所有视图中的一切都很好。我可以在所有这些中看到圆角。但是当我向上滚动到上一个项目时。现在,这些角落在角落里失去了透明度,除了列表中的第三项外,其他所有地方都变黑了。 Canvas在onDraw中也有isOpaque = true
。我尝试了很多东西,但似乎没有任何效果。这是代码
public class RoundedImageView extends ImageView
{
private Paint mPaint;
private int mCornerRadius = 0;
private boolean mRoundedTopLeft = true, mRoundedBottomLeft = true, mRoundedTopRight = true, mRoundedBottomRight = true;
public void setCornerRadius(int mCornerRadius)
{
this.mCornerRadius = mCornerRadius;
}
public void RoundCorners(boolean isRoundedTopLeft, boolean isRoundedTopRight, boolean isRoundedBottomLeft, boolean isRoundedBottomRight)
{
mRoundedTopLeft = isRoundedTopLeft;
mRoundedBottomLeft = isRoundedBottomLeft;
mRoundedBottomRight = isRoundedBottomRight;
mRoundedTopRight = isRoundedTopRight;
}
public RoundedImageView(Context context)
{
super(context);
if (Build.VERSION.SDK_INT >= 11)
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
setupPaint();
}
public RoundedImageView(Context context, AttributeSet attrs)
{
super(context, attrs);
if (Build.VERSION.SDK_INT >= 11)
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
setupPaint();
}
public RoundedImageView(Context context, AttributeSet attrs, int defStyleAttr)
{
super(context, attrs, defStyleAttr);
if (Build.VERSION.SDK_INT >= 11)
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
setupPaint();
}
@TargetApi(21)
public RoundedImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)
{
super(context, attrs, defStyleAttr, defStyleRes);
if (Build.VERSION.SDK_INT >= 11)
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
setupPaint();
}
private Paint setupPaint()
{
mPaint = new Paint();
mPaint.setColor(Color.TRANSPARENT);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setStrokeWidth(1);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
return mPaint;
}
@Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
Path path = RoundedRect(0, 0, getWidth(), getHeight(), mCornerRadius, mCornerRadius,
mRoundedTopLeft, mRoundedTopRight, mRoundedBottomRight, mRoundedBottomLeft);
canvas.drawPath(path, mPaint);
}
public static Path RoundedRect(
float left, float top, float right, float bottom, float rx, float ry,
boolean tl, boolean tr, boolean br, boolean bl)
{
Path path = new Path();
if (rx < 0) rx = 0;
if (ry < 0) ry = 0;
float width = right - left;
float height = bottom - top;
if (rx > width / 2) rx = width / 2;
if (ry > height / 2) ry = height / 2;
float widthMinusCorners = (width - (2 * rx));
float heightMinusCorners = (height - (2 * ry));
path.moveTo(right, top + ry);
if (tr)
path.rQuadTo(0, -ry, -rx, -ry);//top-right corner
else
{
path.rLineTo(0, -ry);
path.rLineTo(-rx, 0);
}
path.rLineTo(-widthMinusCorners, 0);
if (tl)
path.rQuadTo(-rx, 0, -rx, ry); //top-left corner
else
{
path.rLineTo(-rx, 0);
path.rLineTo(0, ry);
}
path.rLineTo(0, heightMinusCorners);
if (bl)
path.rQuadTo(0, ry, rx, ry);//bottom-left corner
else
{
path.rLineTo(0, ry);
path.rLineTo(rx, 0);
}
path.rLineTo(widthMinusCorners, 0);
if (br)
path.rQuadTo(rx, 0, rx, -ry); //bottom-right corner
else
{
path.rLineTo(rx, 0);
path.rLineTo(0, -ry);
}
path.rLineTo(0, -heightMinusCorners);
path.close();//Given close, last lineto can be removed.
path.setFillType(Path.FillType.INVERSE_EVEN_ODD);
return path;
}
}
我已经尝试过的:
- 在 ViewHolder
中设置 isRecyclable false
在绘画中设置不同的 PorterDuff 模式
LAYER_TYPE_HARDWARE(硬件加速)为此视图
setDrawingCacheBackgroundColor(0x00000000);
在构造函数中
setLayerType(View.LAYER_TYPE_SOFTWARE, paint);
在此函数中传递绘画
尝试在 super.onDraw()
之前使 canvas 透明
更新:
经过大量摆弄后,我得出结论,每当我的 viewHolder 的视图超出屏幕时。它的所有 alpha 通道都变黑了。我觉得它必须对 setLayerType(View.LAYER_TYPE_SOFTWARE, null);
做些什么
通过使父软件加速来工作。
我把
解决了
if (Build.VERSION.SDK_INT >= 11)
view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
在我的 ViewHolder 的构造函数中。即使我为任何父容器视图启用了软件加速,它也能正常工作。
现在我不知道为什么会这样。
我有一个自定义 ImageView,它覆盖 onDraw 方法以使用 Path 裁剪角以给出给定半径的圆角。我有一个 RecyclerView,我在所有 4 个项目中都有这些自定义 ImageView。现在的问题是这个自定义 ImageView 首次出现在列表中时呈现良好。一次只能容纳 2 个屏幕。当我向下滚动时,所有视图中的一切都很好。我可以在所有这些中看到圆角。但是当我向上滚动到上一个项目时。现在,这些角落在角落里失去了透明度,除了列表中的第三项外,其他所有地方都变黑了。 Canvas在onDraw中也有isOpaque = true
。我尝试了很多东西,但似乎没有任何效果。这是代码
public class RoundedImageView extends ImageView
{
private Paint mPaint;
private int mCornerRadius = 0;
private boolean mRoundedTopLeft = true, mRoundedBottomLeft = true, mRoundedTopRight = true, mRoundedBottomRight = true;
public void setCornerRadius(int mCornerRadius)
{
this.mCornerRadius = mCornerRadius;
}
public void RoundCorners(boolean isRoundedTopLeft, boolean isRoundedTopRight, boolean isRoundedBottomLeft, boolean isRoundedBottomRight)
{
mRoundedTopLeft = isRoundedTopLeft;
mRoundedBottomLeft = isRoundedBottomLeft;
mRoundedBottomRight = isRoundedBottomRight;
mRoundedTopRight = isRoundedTopRight;
}
public RoundedImageView(Context context)
{
super(context);
if (Build.VERSION.SDK_INT >= 11)
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
setupPaint();
}
public RoundedImageView(Context context, AttributeSet attrs)
{
super(context, attrs);
if (Build.VERSION.SDK_INT >= 11)
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
setupPaint();
}
public RoundedImageView(Context context, AttributeSet attrs, int defStyleAttr)
{
super(context, attrs, defStyleAttr);
if (Build.VERSION.SDK_INT >= 11)
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
setupPaint();
}
@TargetApi(21)
public RoundedImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)
{
super(context, attrs, defStyleAttr, defStyleRes);
if (Build.VERSION.SDK_INT >= 11)
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
setupPaint();
}
private Paint setupPaint()
{
mPaint = new Paint();
mPaint.setColor(Color.TRANSPARENT);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setStrokeWidth(1);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
return mPaint;
}
@Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
Path path = RoundedRect(0, 0, getWidth(), getHeight(), mCornerRadius, mCornerRadius,
mRoundedTopLeft, mRoundedTopRight, mRoundedBottomRight, mRoundedBottomLeft);
canvas.drawPath(path, mPaint);
}
public static Path RoundedRect(
float left, float top, float right, float bottom, float rx, float ry,
boolean tl, boolean tr, boolean br, boolean bl)
{
Path path = new Path();
if (rx < 0) rx = 0;
if (ry < 0) ry = 0;
float width = right - left;
float height = bottom - top;
if (rx > width / 2) rx = width / 2;
if (ry > height / 2) ry = height / 2;
float widthMinusCorners = (width - (2 * rx));
float heightMinusCorners = (height - (2 * ry));
path.moveTo(right, top + ry);
if (tr)
path.rQuadTo(0, -ry, -rx, -ry);//top-right corner
else
{
path.rLineTo(0, -ry);
path.rLineTo(-rx, 0);
}
path.rLineTo(-widthMinusCorners, 0);
if (tl)
path.rQuadTo(-rx, 0, -rx, ry); //top-left corner
else
{
path.rLineTo(-rx, 0);
path.rLineTo(0, ry);
}
path.rLineTo(0, heightMinusCorners);
if (bl)
path.rQuadTo(0, ry, rx, ry);//bottom-left corner
else
{
path.rLineTo(0, ry);
path.rLineTo(rx, 0);
}
path.rLineTo(widthMinusCorners, 0);
if (br)
path.rQuadTo(rx, 0, rx, -ry); //bottom-right corner
else
{
path.rLineTo(rx, 0);
path.rLineTo(0, -ry);
}
path.rLineTo(0, -heightMinusCorners);
path.close();//Given close, last lineto can be removed.
path.setFillType(Path.FillType.INVERSE_EVEN_ODD);
return path;
}
}
我已经尝试过的: - 在 ViewHolder
中设置 isRecyclable false在绘画中设置不同的 PorterDuff 模式
LAYER_TYPE_HARDWARE(硬件加速)为此视图
setDrawingCacheBackgroundColor(0x00000000);
在构造函数中setLayerType(View.LAYER_TYPE_SOFTWARE, paint);
在此函数中传递绘画尝试在
super.onDraw()
之前使 canvas 透明
更新:
经过大量摆弄后,我得出结论,每当我的 viewHolder 的视图超出屏幕时。它的所有 alpha 通道都变黑了。我觉得它必须对 setLayerType(View.LAYER_TYPE_SOFTWARE, null);
通过使父软件加速来工作。
我把
解决了if (Build.VERSION.SDK_INT >= 11)
view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
在我的 ViewHolder 的构造函数中。即使我为任何父容器视图启用了软件加速,它也能正常工作。
现在我不知道为什么会这样。