我目前正在开发一款Android应用,可以显示多个图像(ImageView's
)堆叠在一起。以下是当前配置图层的方式:
我面临的问题是前景层。我将onClick()
方法分配给imageview,但是调用该方法是否它们是否可以看到可见的图像部分以及包含透明度的部分。我只希望在用户单击该图像视图中不透明的部分时调用前景ImageView onClick()
方法。
这就是场景:
对角线代表前景图像的透明部分。如果用户触摸此空间,我希望它访问背景图像而不是前景图像。感谢您提供的任何帮助。
以下是我实施的解决方案(感谢下面的回答):
//ontouchlistener - gets X and Y from event
private void setClick(View view)
{
view.setOnTouchListener(new View.OnTouchListener()
{
public boolean onTouch(View v, MotionEvent event)
{
int imageId = getImageId((int)event.getX(), (int)event.getY());
if (imageId >= 0)
performActions(imageId);
return false;
}
});
}
//get the ID of the first imageview (starting from foreground,
//working backwards) which contains a non-transparent pixel
private int getImageId(int x, int y)
{
ViewGroup parent = (ViewGroup) findViewById(R.id.relative_layout);
for (int a = parent.getChildCount()-1; a >= 0; a--)
{
if (parent.getChildAt(a) instanceof ImageView)
if (!checkPixelTransparent((ImageView)parent.getChildAt(a), x, y))
return parent.getChildAt(a).getId();
}
return -1;
}
//get bitmap from imageview, get pixel from x, y coord
//check if pixel is transparent
private boolean checkPixelTransparent(ImageView iv, int x, int y)
{
Bitmap bitmap = ((BitmapDrawable) iv.getDrawable()).getBitmap();
if (Color.alpha(bitmap.getPixel(x, y)) == 0)
return true;
else
return false;
}
答案 0 :(得分:33)
This one sample使ImageView的透明区域无法点击。
<强> ImageView的:强>
ImageView imgView= (ImageView) findViewById(R.id.color_blue);
imgView.setDrawingCacheEnabled(true);
imgView.setOnTouchListener(changeColorListener);
<强> OnTouchListener:强>
private final OnTouchListener changeColorListener = new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
Bitmap bmp = Bitmap.createBitmap(v.getDrawingCache());
int color = bmp.getPixel((int) event.getX(), (int) event.getY());
if (color == Color.TRANSPARENT)
return false;
else {
//code to execute
return true;
}
}
};
答案 1 :(得分:3)
如果您的前景图像不仅仅是一个矩形而是复杂的图像,并且您确实需要触摸是像素精确的,那么您可以使用
http://developer.android.com/reference/android/view/View.OnTouchListener.html
foregroundImage.setOnTouchListener(new View.OnTouchListener(){...});
回调中的MotionEvent
将包含所发生的操作类型(例如,触摸起来)和确切位置。
如果您知道显示的前景图像的确切大小,您可以确定它的哪个像素被点击,然后检查该像素的alpha是否为0.或者,如果图像是,则可能需要应用一些缩放缩放。这可能变得非常棘手,因为取决于屏幕尺寸和比例,图像可能已被不同地缩放/定位。这还取决于您使用的布局。
为了检查像素值,您可能需要在内存中保留包含前景图像数据的Bitmap
对象。
答案 2 :(得分:0)
Bitmap.createBitmap(v.getDrawingCache()
和imageView.setDrawingCacheEnabled(true)
已贬值,因此您可以按照以下代码段进行操作:
imageView.setOnTouchListener { v, event ->
val bmp = convertViewToDrawable(v)
val color: Int = bmp.getPixel(event.x.toInt(), event.y.toInt())
if (color == Color.TRANSPARENT)
return@setOnTouchListener false
else {
Toast.makeText(baseContext, "image clicked", Toast.LENGTH_SHORT).show()
return@setOnTouchListener true
}
}
private fun convertViewToDrawable(view: View): Bitmap {
val b = Bitmap.createBitmap(view.measuredWidth, view.measuredHeight,
Bitmap.Config.ARGB_8888)
val c = Canvas(b)
c.translate((-view.scrollX).toFloat(), (-view.scrollY).toFloat())
view.draw(c)
return b
}