Making skewed view in android
The best solution is to divide a normalised image into polygons where each polygons represents a clickable area. You then attach a OnTouchListener and check if the normalized touch coordinate is within the polygon. This solution requires a bit of work from the programmer plus the implementation of a geometrical algorithm. I will not go further with this solution, but instead present you with the easiest one that takes you the least amount of time to implement. I am guessing that this is what you want, I hope I'm right :).
The easiest solution without third party libraries
Note that this solution is not memory effecient and should be used with caution
1. You cut up your image into several images of the same size where each image only contains a single clickable area and the rest is transparent. If I use the first image in your question as an example then one of these images will look like this:
(source: magma.is)
2. Now you overlay these images in multiple overlapping ImageViews
....
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageView
android:id="@+id/img_cut_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="center"
android:src="@drawable/image_cut_1" />
<ImageView
android:id="@+id/img_cut_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="center"
android:src="@drawable/image_cut_2" />
...
3. In your Activity/Fragment you set the same OnTouchListener to all the ImageViews. There you discover by transparency elimination which ImageView was truly touched and then you have the information you need about which area of the image (or button if you will) was pressed.
@Override
public boolean onTouch(View v, MotionEvent me) {
if (me.getAction() == MotionEvent.ACTION_DOWN) {
int nTouchX = (int)me.getX();
int nTouchY = (int)me.getY();
if (v == imageCut1) {
Bitmap bm = ((BitmapDrawable)imageCut1.getDrawable()).getBitmap();
if (bm.getPixel(nTouchX, nTouchY) != 0) {
// non-transparent pixel touched, we found our view, receive further motion events. This can also be set false and code inserted here.
return true;
}
// transparent pixel touched, do not receive further motion events.
return false;
}
if (v == imageCut2) {
...
If you only want a user tap you can eiter continue using OnClick in parallel or better, use the MotionEvent.ACTION_UP action and check for tap drift and max time delay between the DOWN and UP motion events. Something like this in MotionEvent.ACTION_UP: ( and note that only the "correct" ImageView will give you this motion event since we discarded further motion events for the other views )
if (
mMainDragStartX <(me.getX()+TAP_DRIFT_TOLERANCE) &&
mMainDragStartX > (me.getX() -TAP_DRIFT_TOLERANCE) &&
mMainDragStartY < (me.getY() + TAP_DRIFT_TOLERANCE) &&
mMainDragStartY > (me.getY() - TAP_DRIFT_TOLERANCE) &&
((SystemClock.elapsedRealtime() - mMainDraggingStarted) < SINGLE_TAP_MAX_TIME)) {
// The user has tapped!
...