How to prevent onClick method on transparent portion of a PNG-loaded ImageView

前端 未结 3 499
北荒
北荒 2020-12-02 21:23

I am currently developing an Android app that displays multiple images (as ImageView\'s) stacked on top of each other. Here is how the layers are currently con

相关标签:
3条回答
  • 2020-12-02 21:51

    This one sample makes ImageView's transparent area not clickable.

    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;
            }
        }
    };
    
    0 讨论(0)
  • 2020-12-02 21:52

    If your foreground image is not just a rect but a complex image and you really need that the touch is pixel-precise, you may use

    http://developer.android.com/reference/android/view/View.OnTouchListener.html

    foregroundImage.setOnTouchListener(new View.OnTouchListener(){...});
    

    The MotionEvent in the callback will contain what kind of action happened (e.g. Touch up) and the exact location.

    If you know the exact size of the foreground image as it is displayed, you can figure out which pixel of it was clicked, then check if that pixel's alpha is 0. Or you may need to apply some scaling if the image was scaled. This may get quite tricky since depending on the screen size and proportions the image may have been scaled/positioned differently. This also depends on the layouts your were using.

    For the check of the pixel value you'd probably need to keep in memory the Bitmap object containing your foreground's image data as well.

    Frankly, I doubt you'd really need all that precision unless your foreground image is really of a very irregular shape.

    0 讨论(0)
  • 2020-12-02 21:59

    Bitmap.createBitmap(v.getDrawingCache() and imageView.setDrawingCacheEnabled(true) are depreciated so you can do this by the following snippet code:

    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
        }
    
    0 讨论(0)
提交回复
热议问题