Android-触按可擦除部分前景图像视图以显示背景视图
所以我一天中的大部分时间都在努力解决这个问题。假设我有一个自定义的ImageView,我想覆盖在背景视图上(都在RelativeLayout中),当触摸它时,它会像MS Paint中的擦除工具一样擦除视图源位图的一部分,从而暴露其下方的视图。我已经检查了几乎所有的线程(如),他们建议在Paint对象中使用PorterDuff SRC模式,并在源位图的ARGB_8888阴影副本中创建画布以应用遮罩 另外,我不能提前设置覆盖的来源,因为我必须通过网络下载它,以便ImageView的缩放类型为我处理缩放 每次我覆盖onDraw时,当我在IV的位图上应用擦除时,它会显示一个黑色背景,而不是它下面的视图,即使我将背景设置为透明。因此,为了揭开背景视图的面纱,我已经到了最后一步了 以下是我目前掌握的情况: 视图构造函数:Android-触按可擦除部分前景图像视图以显示背景视图,android,bitmap,imageview,erase,ondraw,Android,Bitmap,Imageview,Erase,Ondraw,所以我一天中的大部分时间都在努力解决这个问题。假设我有一个自定义的ImageView,我想覆盖在背景视图上(都在RelativeLayout中),当触摸它时,它会像MS Paint中的擦除工具一样擦除视图源位图的一部分,从而暴露其下方的视图。我已经检查了几乎所有的线程(如),他们建议在Paint对象中使用PorterDuff SRC模式,并在源位图的ARGB_8888阴影副本中创建画布以应用遮罩 另外,我不能提前设置覆盖的来源,因为我必须通过网络下载它,以便ImageView的缩放类型为我处理缩
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
paint.setColor(Color.TRANSPARENT);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(STROKE_WIDTH);
paint.setAntiAlias(true);
重写setImageBitmap以从重新配置的源位图设置画布:
public void setImageBitmap(Bitmap bitmap){
super.setImageBitmap(bitmap);
Drawable bd = getDrawable();
if(bd == null){
return;
}
Bitmap fullSizeBitmap = ((BitmapDrawable) bd).getBitmap();
overlay = fullSizeBitmap.copy(Config.ARGB_8888, true);
c2 = new Canvas(overlay);
}
onDraw方法:
protected void onDraw(Canvas canvas) {
/*
* Override paint call by re-drawing the view's Bitmap first, then overlaying our path on top of it
*/
Drawable bd = getDrawable();
if(bd == null){
return;
}
Bitmap fullSizeBitmap = ((BitmapDrawable) bd).getBitmap();
if(fullSizeBitmap != null && c2 != null){
canvas.drawColor(Color.TRANSPARENT);
c2.drawBitmap(fullSizeBitmap, 0, 0, null);
c2.drawPath(path, paint);
canvas.drawBitmap(overlay, 0, 0, null);
}
}
我知道这是一个非常古老的问题,但下面是我为解决一个类似的问题所做的。也许这对将来的人有帮助 从API级别11及以上,您必须为
ImageView
指定这段代码,以便在后面而不是黑色区域显示图像
if (Build.VERSION.SDK_INT >= 11) {
imageview.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
这帮助我成功地显示了背景图像你能试试这个解决方案吗?它将帮助你在android on touch中擦除图像。。或下载
这可能不是最好的方法,但这是一个想法。在要使其透明的ImageView上,只需将一个透明的.png图像设置为背景,而不必进行画布绘制。也就是说,你可以在你的应用程序中制作一个小小的.png图像和软件包。我的资源中已经有了这样的图像,但我不知道这比a)将IV的背景设置为空或b)将其颜色和画布设置为透明有什么好处?不过我会试一试。不,即使设置一个透明的PNG作为背景也没什么区别:-(您可以使用
addView
添加稍后将被删除的图像,然后在触摸屏上调用removeView
。我想这可能会起作用,也可能不会起作用,这取决于您实际希望应用程序做什么。我没有看到您的代码中有任何错误,但我猜是有一些愚蠢的东西破坏了整个操作。通常我的无法解释的错误是由于我的粗心。我可能错了,但可能很简单。如果你完全伪造了效果会怎样?创建一个同时包含顶部图像(设置为可见)和底部视图组件(设置为不可见)的视图。单击顶部图像时,使其不可见,并使其他视图组件可见。但是api<11如何?对于较旧的api级别,这将不需要。但是,为什么较旧的api会出现黑线,但我的代码在android 4.1上运行良好,我的问题是,这段代码会禁用特定vie的硬件加速w(android api 11+)。看看这个()链接,看看这是否有帮助。如果没有,你可能必须在清单中禁用硬件加速,但还没有完全弄清楚。你还可以查看开发者文档以了解更多信息
public class MainActivity extends Activity {
Bitmap bp;
Canvas bitmapCanvas;
DrawView drawImg;
LinearLayout ln1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ln1 = (LinearLayout) findViewById(R.id.ln1);
drawImg = new DrawView(this);
ln1.addView(drawImg);
}
public class DrawView extends View implements View.OnTouchListener {
private int x = 0;
private int y = 0;
Bitmap bitmap;
Path circlePath;
Paint circlePaint;
private final Paint paint = new Paint();
private final Paint eraserPaint = new Paint();
public DrawView(Context context){
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
this.setOnTouchListener(this);
// Set background
this.setBackgroundColor(Color.CYAN);
bp = BitmapFactory.decodeResource(getResources(), R.drawable.bg);
// Set bitmap
bitmap = Bitmap.createBitmap(320, 480, Bitmap.Config.ARGB_8888);
bitmapCanvas = new Canvas();
bitmapCanvas.setBitmap(bitmap);
bitmapCanvas.drawColor(Color.TRANSPARENT);
bitmapCanvas.drawBitmap(bp, 0, 0, null);
circlePath = new Path();
circlePaint = new Paint();
circlePaint.setAntiAlias(true);
circlePaint.setColor(Color.BLUE);
circlePaint.setStyle(Paint.Style.STROKE);
circlePaint.setStrokeJoin(Paint.Join.MITER);
circlePaint.setStrokeWidth(4f);
// Set eraser paint properties
eraserPaint.setAlpha(0);
eraserPaint.setStrokeJoin(Paint.Join.ROUND);
eraserPaint.setStrokeCap(Paint.Cap.ROUND);
eraserPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
eraserPaint.setAntiAlias(true);
}
@Override
public void onDraw(Canvas canvas) {
canvas.drawBitmap(bitmap, 0, 0, paint);
bitmapCanvas.drawCircle(x, y, 30, eraserPaint);
canvas.drawPath(circlePath, circlePaint);
}
public boolean onTouch(View view, MotionEvent event) {
x = (int) event.getX();
y = (int) event.getY();
bitmapCanvas.drawCircle(x, y, 30, eraserPaint);
circlePath.reset();
circlePath.addCircle(x, y, 30, Path.Direction.CW);
int ac=event.getAction();
switch(ac){
case MotionEvent.ACTION_UP:
Toast.makeText(MainActivity.this, String.valueOf(x), Toast.LENGTH_SHORT).show();
circlePath.reset();
break;
}
invalidate();
return true;
}
}
}