The skew layout can like this or simple like this.
How to make that?
The best solution is to divide a normalized 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.Firstly, cutting 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:
Piece 1 |
Piece 2 |
Now, copy all of above to
drawable
folder of your android project and start coding.
Define MainActivity.java
which contains a picture with two clickable polygons. Here is code:
package com.example.testframeimages;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
public class MainActivity extends Activity implements OnTouchListener {
private ImageView i1;
private ImageView i2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
i1 = (ImageView) findViewById(R.id.i1);
i2 = (ImageView) findViewById(R.id.i2);
// set mutual ontouchlistener
i1.setOnTouchListener(this);
i2.setOnTouchListener(this);
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouch(View v, MotionEvent me) {
if (me.getAction() == MotionEvent.ACTION_DOWN) { // this is touch
int nTouchX = (int) me.getX();
int nTouchY = (int) me.getY();
if (v == i1) {
Bitmap bm = ((BitmapDrawable) i1.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.
Log.i("Touch", "i1: green touch");
return true;
}
// transparent pixel touched, do not receive further motion
// events.
return false;
} else if (v == i2) {
Bitmap bm = ((BitmapDrawable) i2.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.
Log.i("Touch", "i2:yellow");
return true;
}
// transparent pixel touched, do not receive further motion
// events.
return false;
}
} else if (me.getAction() == MotionEvent.ACTION_UP) {
// perform click action
int x = (int) me.getX();
int y = (int) me.getY();
if (v == i1) {
Bitmap bm = ((BitmapDrawable) i1.getDrawable()).getBitmap();
if ((x >= 0) && (y >= 0) && (y < bm.getHeight())
&& (x < bm.getWidth())) {
if (bm.getPixel(x, y) != 0) {
// non-transparent pixel touched, we found our view,
// receive
// further motion events. This can also be set false and
// code inserted here.
Log.i("Click", "i1: green click!");
Intent intent = new Intent(MainActivity.this,
TestActivity.class);
intent.putExtra("Clicked Area", "green clicked");
startActivity(intent);
return true;
}
}
// transparent pixel touched, do not receive further motion
// events.
return false;
} else if (v == i2) {
Bitmap bm = ((BitmapDrawable) i2.getDrawable()).getBitmap();
if ((x >= 0) && (y >= 0) && (y < bm.getHeight())
&& (x < bm.getWidth())) {
if (bm.getPixel(x, y) != 0) {
// non-transparent pixel touched, we found our view,
// receive
// further motion events. This can also be set false and
// code inserted here.
Log.i("Click", "i2: yellow click!");
Intent intent = new Intent(MainActivity.this,
TestActivity.class);
intent.putExtra("Clicked Area", "yellow clicked");
startActivity(intent);
return true;
}
}
// transparent pixel touched, do not receive further motion
// events.
return false;
}
}
return false;
}
}
And file activity_main.xml
:
activity_main.xml
Next, we must define a destination activity which started when clicking at each polygon, and show information from this action:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.testframeimages.MainActivity" >
<FrameLayout
android:id="@+id/frame"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageView
android:id="@+id/i1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="center"
android:src="@drawable/abc" />
<ImageView
android:id="@+id/i2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="center"
android:src="@drawable/def" />
</FrameLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="each part of image are clickable" />
</RelativeLayout>
TestActivity.java
And it's layout:
package com.example.testframeimages;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class TestActivity extends Activity {
private String intentString;
private TextView text;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
text = (TextView) findViewById(R.id.text);
getDataFromIntent();
setText();
}
private void setText() {
text.setText(intentString);
if (intentString.equals("yellow clicked")) {
text.setTextColor(getResources().getColor(R.color.yellow));
} else {
text.setTextColor(getResources().getColor(R.color.green));
}
}
private void getDataFromIntent() {
Intent intent = getIntent();
intentString = intent.getStringExtra("Clicked Area");
Log.i("Test", intentString);
}
}
activity_test.xml
File <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textSize="18sp"
android:gravity="center"
android:text="@string/test" />
</RelativeLayout>
colors.xml
to define text colors:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="yellow">#CC9900</color>
<color name="green">#008800</color>
</resources>
strings.xml
to define strings value:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Skew layout</string>
<string name="hello_world">Hello world!</string>
<string name="action_settings">Settings</string>
<string name="test">Test</string>
</resources>
(sorry for ads in download link)