Android - Simple making skew layout

    Hi, readers! Today I present a simple way to make a skew layout in Android programming. Each part of screen (above black line or under it ) are clickable.
    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
<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>
    Next, we must define a destination activity which started when clicking at each polygon, and show information from this action:
TestActivity.java
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);
    }
}
    And it's layout:
activity_test.xml
<?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>
File 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>


File 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>
    Finally, after running program, our result like this:

pic name pic name pic name

(sorry for ads in download link)

Share


Previous post
« Prev Post
Next post