Im looking for a way to make some type of skewed view in android(Imageview , Button or frame)
anything that i can implement onclick on it.
there is some style in windows phone like this :
or something like this :
Each part of screen (above black line or under it ) are clickable and make new activity apears.I have no problem to show grid with different column size with using staggeredgridview. but i guess for this approach i should make costume layout frame and not grid ?
i find another sample of this on play.google.com :
its some kinda cover making somewhere and image can be changed but without onclick ability on each view.
Edit : Deploy Suggestion from Ernir :
public abstract class MainActivity extends Activity implements View.OnTouchListener {
final ImageView iv= (ImageView)findViewById(R.id.img_cut_1);
final ImageView iv2= (ImageView)findViewById(R.id.img_cut_2);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.img_cut_1).setOnTouchListener(new MyTouchListener());
}
private final class MyTouchListener implements OnTouchListener {
@Override
public boolean onTouch(View v, MotionEvent me) {
if (me.getAction() == MotionEvent.ACTION_DOWN) {
int vid = v.getId();
int nTouchX = (int)me.getX();
int nTouchY = (int)me.getY();
if (vid == R.id.img_cut_1) {
Bitmap bm = ((BitmapDrawable)iv.getDrawable()).getBitmap();
if (bm.getPixel(nTouchX, nTouchY) != 0) {
Log.i("MyActivity", "img_cut_1 true");
return true;
}
return false;
}
if (vid == R.id.img_cut_2) {
Bitmap bm = ((BitmapDrawable)iv2.getDrawable()).getBitmap();
if (bm.getPixel(nTouchX, nTouchY) != 0) {
Log.i("MyActivity", "img_cut_2 true");
return true;
}
return false;
}
}
return true;
}
}
and layout :
<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=".MainActivity" >
<FrameLayout
android:id="@+id/frame"
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/ic_launcher" />
</FrameLayout>
</RelativeLayout>
but getting this error :
01-06 11:06:33.242: E/AndroidRuntime(15737): FATAL EXCEPTION: main
01-06 11:06:33.242: E/AndroidRuntime(15737): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.test.com/com.example.test.com.MainActivity}: java.lang.InstantiationException: com.example.test.com.MainActivity
01-06 11:06:33.242: E/AndroidRuntime(15737): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1573)
01-06 11:06:33.242: E/AndroidRuntime(15737): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1667)
01-06 11:06:33.242: E/AndroidRuntime(15737): at android.app.ActivityThread.access$1500(ActivityThread.java:117)
01-06 11:06:33.242: E/AndroidRuntime(15737): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
01-06 11:06:33.242: E/AndroidRuntime(15737): at android.os.Handler.dispatchMessage(Handler.java:99)
01-06 11:06:33.242: E/AndroidRuntime(15737): at android.os.Looper.loop(Looper.java:130)
01-06 11:06:33.242: E/AndroidRuntime(15737): at android.app.ActivityThread.main(ActivityThread.java:3687)
01-06 11:06:33.242: E/AndroidRuntime(15737): at java.lang.reflect.Method.invokeNative(Native Method)
01-06 11:06:33.242: E/AndroidRuntime(15737): at java.lang.reflect.Method.invoke(Method.java:507)
01-06 11:06:33.242: E/AndroidRuntime(15737): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
01-06 11:06:33.242: E/AndroidRuntime(15737): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
01-06 11:06:33.242: E/AndroidRuntime(15737): at dalvik.system.NativeStart.main(Native Method)
01-06 11:06:33.242: E/AndroidRuntime(15737): Caused by: java.lang.InstantiationException: com.example.test.com.MainActivity
01-06 11:06:33.242: E/AndroidRuntime(15737): at java.lang.Class.newInstanceImpl(Native Method)
01-06 11:06:33.242: E/AndroidRuntime(15737): at java.lang.Class.newInstance(Class.java:1409)
01-06 11:06:33.242: E/AndroidRuntime(15737): at android.app.Instrumentation.newActivity(Instrumentation.java:1021)
01-06 11:06:33.242: E/AndroidRuntime(15737): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1565)
01-06 11:06:33.242: E/AndroidRuntime(15737): ... 11 more
ive tried to add the whole method inside another activity but that didnt help . ive add the method inside class because of the word "same OnTouchListener to all the ImageViews" you mentioned.
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 :).
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!
...
You have to customize layouts, let me point you to one as an example
QuiltViewLIbrary
StaggeredGridView
StaggeredGridView is more like Pinteerest's. So you will use one of those as template and code a new GridLayout Class that puts the images in an change to make trapezoids or triangles.
No, its not a non-grid layout..you have to customize a gridlayout.
The tilling math will be somewhat Penrose, do a google search and you will find java libs for that purpose.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With