Как предотвратить метод onClick на прозрачной части загруженного PNG ImageView
В настоящее время я разрабатываю приложение для Android, которое отображает несколько изображений (как ImageView's
), уложенных друг на друга. Вот как настроены слои:
- Фоновый слой: масштабирует весь экран, должен быть доступен для клика
- Уровень переднего плана: масштабирует весь экран, должен быть доступен для кликов,
содержит прозрачность, которая позволяет пользователю видеть некоторые из
фоновый слой
Проблема, с которой я сталкиваюсь, - это слой переднего плана. Я назначаю метод onClick()
для изображения, но метод вызывается, попадают ли они на часть видимого изображения, а также на часть, содержащую прозрачность. Мне нужен только метод переднего плана 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;
}
Ответы
Ответ 1
Этот один образец делает прозрачную область 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;
}
}
};
Ответ 2
Если ваше изображение переднего плана - это не просто прямоугольное, а сложное изображение, и вам действительно нужно, чтобы прикосновение было точным для пикселя, вы можете использовать
http://developer.android.com/reference/android/view/View.OnTouchListener.html
foregroundImage.setOnTouchListener(new View.OnTouchListener(){...});
MotionEvent
в обратном вызове будет содержать действия (например, Touch up) и точное местоположение.
Если вы знаете точный размер изображения переднего плана, как он отображается, вы можете определить, какой пиксель его был нажат, а затем проверить, является ли этот пиксель альфа 0. Или вам может потребоваться применить некоторое масштабирование, если изображение было масштабируется. Это может стать довольно сложным, поскольку в зависимости от размера экрана и пропорций изображение может быть масштабировано/расположено по-разному. Это также зависит от используемых вами макетов.
Для проверки значения пикселя вам, вероятно, потребуется сохранить в памяти объект Bitmap
, содержащий ваши данные переднего плана.
Честно говоря, я сомневаюсь, что вам действительно понадобится вся эта точность, если ваше изображение переднего плана не имеет очень неправильной формы.
Ответ 3
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)
[email protected] false
else {
Toast.makeText(baseContext, "image clicked", Toast.LENGTH_SHORT).show()
[email protected] 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
}