(Android Layout) Solution for the "Place" button on top of an irregularly shaped image or detecting the touch (touchable area) of a specific area of ​​the image?

In my Android application, I have three irregular shapes around the world, as shown below:

enter image description here

So, I placed all this image in the layout. Globe is just an image .There is no role of globe here. Now I want to place one button on top of each irregularly shaped image located around the world.

The button is always rectangular, but I want to get touch event for irregular shape,not for rectangular area. So, how can I put three buttons on these three irregularly shaped ones or is there some solution? so that in an event you can handle different events for each button?

I have no idea how to achieve this. Please help me with this.

Any tips or suggestions?

Any help would be appreciated.

+5
source share
4 answers

From the above answers, I got a hint and finally got a Solution, as shown below:

What I did is:

Used by RelativeLayout in XML file

Used by ImageView, as shown below:

  <ImageView android:id="@+id/btn1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/glob2" android:layout_marginBottom="24dp" android:layout_marginLeft="80.5dp" android:contentDescription="@string/profile_picture_description" android:src="@drawable/pick_matches_background" /> 

Here I set the field accordingly (left / right / bottom / top).

In action

Announces

 Bitmap btmp; and ImageView img; 

In the onCreate Method,

  // initialized image view img = (ImageView) findViewById(R.id.btn1); img.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // call your method here } }); StateListDrawable sdCreateTrip = (StateListDrawable) img .getDrawable(); btmp = ((BitmapDrawable) sdCreateTrip.getCurrent()) .getBitmap(); 

Now you are ready.

0
source

I have not tested this, but I think it will work. I am sure you will have to configure it and make corrections.

Create a copy of the background image in which the three buttons are three different colors without aliasing and all the other pixels are pure black. It must be PNG, so it will not have JPG compression artifacts. This will be your mask. You can just use pure red, green and blue, since you only have three buttons. This could probably be a lower resolution than the original image if the aspect ratio is the same.

Subclass ImageView and use your subclass to paint the background. Pass your subclass the version of ImageView into your mask image as a bitmap.

 class TouchMaskImageView extends ImageView { ...constructors public void setTouchMask(Bitmap mask){ this.mMask = mask; } public interface OnTouchedListener{ public void onTouched(MotionEvent event, int colorTouched); public void onTouchCanceled(); } public void setOnTouchedListener(OnTouchedListener listener){ this.mOnTouchedListener = listener; } @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); if (mOnTouchedListener != null && mMask != null ) { if (x >=0 && x < (float)getWidth() && y >=0 && y < (float)getHeight()) { //Next two lines will be more complicated if // you aren't using scaleType fitXY int maskX = (int) x * mMask.getWidth() / getWidth(); int maskY = (int) y * mMask.getWidth() / getHeight(); int maskColor = mask.getPixel(maskX, maskY); mOnTouchedListener.onTouched(event, maskColor); } else if (event.getAction()==MotionEvent.UP){ //released finger outside image view mOnTouchedListener.onTouchCanceled(); } } } } 

Now you can create an OnTouchedListener that handles touch logic similar to a button. He will have to track the status. Here is an example, but I'm not sure if it breaks when there are a few touches. You may also need to set the action mask for the first finger and use getActionMasked () instead of getAction ().

 public void onTouched(MotionEvent event, int colorTouched){ switch(mState){ case STATE_WAITING: if (event.getAction()==MotionEvent.ACTION_DOWN){ switch (colorTouched){ case 0xffff0000: //red mTouchMaskImageView.setImageResource(R.drawable.redButtonDown); mState = STATE_LATCHED_RED; break; case 0xff00ff00: //green mTouchMaskImageView.setImageResource(R.drawable.greenButtonDown); mState = STATE_LATCHED_GREEN; break; case 0xff0000ff: //blue mTouchMaskImageView.setImageResource(R.drawable.blueButtonDown); mState = STATE_LATCHED_BLUE; break; } } break; case STATE_LATCHED_RED: switch (event.getAction()){ case (MotionEvent.ACTION_MOVE): if (colorTouched = 0xffff0000) mTouchMaskImageView.setImageResource(R.drawable.redButtonDown); else mTouchMaskImageView.setImageResource(R.drawable.defaultImage); break; case (MotionEvent.ACTION_UP) if (colorTouched = 0xffff0000) performRedButtonAction(); mTouchMaskImageView.setImageResource(R.drawable.defaultImage); mState = STATE_WAITING; break; } break; case etc. for other two latched colors... break; } } public void onTouchCanceled(){ mTouchMaskImageView.setImageResource(R.drawable.defaultImage); mState = STATE_WAITING; } 

This is somewhat crude, because you need four different copies of your image to represent the four possible states. If you want to take the time to save some memory and make it work faster, you can try to customize the layout with separate images for the three buttons superimposed in the correct positions, and configure them to change the image. But that would be very difficult, given that you would have to ideally line it up for any screen size.

+1
source

The FLAG_WINDOW_IS_OBSCURED flag FLAG_WINDOW_IS_OBSCURED well for me in the past, but it may take some work to work properly. It may be worth a try, but to be honest, I'm still not sure exactly how it determines what is and is not hiding, so it may not be applicable here.

 static OnTouchListener listenerMotionEvent = new OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { if ( (motionEvent.getFlags() | MotionEvent.FLAG_WINDOW_IS_OBSCURED) != MotionEvent.FLAG_WINDOW_IS_OBSCURED ) { return false; // View is not obscured so we pass on the event } // Process the motion event here and return true if you consume it }; 
0
source

Would you crop an image in Photoshop and then put that image in a web view?

0
source

All Articles