如何防止加载PNG的ImageView的透明部分上的onClick方法

时间:2013-03-11 16:08:43

标签: android onclick imageview

我目前正在开发一款Android应用,可以显示多个图像(ImageView's)堆叠在一起。以下是当前配置图层的方式:

  • 背景图层:缩放整个屏幕,必须是可点击的
  • 前景层:缩放整个屏幕,必须是可点击的, 包含透明度,允许用户看到一些 背景图层

我面临的问题是前景层。我将onClick()方法分配给imageview,但是调用该方法是否它们是否可以看到可见的图像部分以及包含透明度的部分。我只希望在用户单击该图像视图中不透明的部分时调用前景ImageView onClick()方法。

这就是场景:

enter image description here

对角线代表前景图像的透明部分。如果用户触摸此空间,我希望它访问背景图像而不是前景图像。感谢您提供的任何帮助。

以下是我实施的解决方案(感谢下面的回答):

//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;
}

3 个答案:

答案 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
    }