4

i have two triangular shaped images that i want to use as button background. i used the frame layout to make overlapping and able to make a desired shape as in picture.

its my final look

Now i just put onclick listener on each button but its not working properly only click on button two works every time.

please help me to find solution.

here is my code mainActivity.java code.

      package com.example.buttontest;

import java.util.Locale;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity implements OnGestureListener{
    private GestureDetector gestureDetector;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        gestureDetector=new GestureDetector(this);

        Button b1=(Button)findViewById(R.id.button2);

        Button b2=(Button)findViewById(R.id.button1);

        b1.setOnTouchListener(new OnTouchListener() {

            public boolean onTouch(View v, MotionEvent e) {
                int width = findViewById(R.id.button1).getWidth();
                int height = findViewById(R.id.button1).getHeight();
                float touchedX = e.getX();
                float touchedY = e.getY();
                boolean inUpperTriangle = (height - touchedY) * width > touchedX * height;
                if(inUpperTriangle==true)
                    Toast.makeText(getApplicationContext(), "upper",Toast.LENGTH_SHORT).show();

                if(inUpperTriangle) gestureDetector.onTouchEvent(e);
                return inUpperTriangle;
            }

        });

        b2.setOnTouchListener(new OnTouchListener() {

            public boolean onTouch(View v, MotionEvent e) {




                int width = findViewById(R.id.button2).getWidth();
                int height = findViewById(R.id.button2).getHeight();
                float touchedX = e.getX();
                float touchedY = e.getY();
                boolean inLowerTriangle = (height - touchedY) * width < touchedX * height;
                if(inLowerTriangle==true)
                    Toast.makeText(getApplicationContext(), "lower",Toast.LENGTH_SHORT).show();
                if(inLowerTriangle) gestureDetector.onTouchEvent(e);
                return inLowerTriangle;
            }
        });




    }


    public boolean onDown(MotionEvent e) {
        // TODO Auto-generated method stub
        return false;
    }


    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
            float velocityY) {
        // TODO Auto-generated method stub
        return false;
    }


    public void onLongPress(MotionEvent e) {
        // TODO Auto-generated method stub

    }


    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
            float distanceY) {
        // TODO Auto-generated method stub
        return false;
    }


    public void onShowPress(MotionEvent e) {
        // TODO Auto-generated method stub

    }


    public boolean onSingleTapUp(MotionEvent e) {
        return true;
    }

}

and my layout file is.

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/FrameLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >

<Button
    android:id="@+id/button2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/button2" />

<Button
    android:id="@+id/button1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/button1" />

please let me know how to get correct clicks on both of these buttons.

here are my drawables.i am using yellow triangle as button 1 image and green as button 2 image. enter image description here

enter image description here

m_kiani
  • 197
  • 4
  • 11
  • The picture looks like interesting drawables. Could you please post them? I would go here with the TouchListener. My answer follows soon. – jboi Nov 05 '13 at 14:06
  • have you solved you problem..plz guide me also – Passion May 22 '14 at 10:39

1 Answers1

3

I would use a TouchListener instead of click listener. A TouchListener can check an event and pass it to the next View, if the current view has no use for it.

So, do the following things:

  • Register a TouchListener on each of the buttons.

  • In the Listener, check, if the touched area is within the triangle. If so, consume the event (e.g. show the Toast) and return true. If not, return false in the listener.

So far so good. Implementing TouchListener is a bit more complicated then implementing click events. See this answer about detecting taps where I've added some short example source for implementing a simple TouchListener that can detect single-tap (effectively clicks) and other gestures and that detects where the user has actually touched.

In your case, you just create two listeners like the one in the link and link them the the two listener.

findViewById(R.id.button1).setOnTouchListener(new OnTouchListener() {...});
findViewById(R.id.button2).setOnTouchListener(new OnTouchListener() {...});

EDIT: With a bit of math you can easily find out which triangle was actually touched. Here is a code snippet to implement with the TouchListeners:

public boolean onTouch(View v, MotionEvent event) {
    int width = findViewById(R.id.button1).getWidth();
    int height = findViewById(R.id.button1).getHeight();
    float touchedX = event.getX();
    float touchedY = event.getY();
    boolean inUpperTriangle = (height - touchedY) * width > touchedX * height;

    if(inUpperTriangle) gestureDetector.onTouchEvent(event);
    return inUpperTriangle;
}

Replace the onTouch form the source in this link with this onTouch method. Create the same method for the second button just with reaction on the lower triangle. You can then detect in onSingleTapUp method of the gesture listener if the button, the listener is linked to was touched and react on it.

Note that the upper, left corner of a View has the coordinates (0,0) and the y-axis increases downwards. Thats the reason for the (height-touchedY).

Community
  • 1
  • 1
jboi
  • 11,324
  • 4
  • 36
  • 43
  • can you explain how to check the touched area is within the triangle.?? – m_kiani Nov 06 '13 at 07:19
  • 1
    That is simple math. I've added some code to give you the actual coordinates to calculate with. The upper, left corner of each view has the coordinates of (0,0) and the y-axis increases from up to down. – jboi Nov 06 '13 at 09:39
  • this things works separately, but when i use frame layout only the lower button touch event performs. and upper half dont do anything. can you tell how to merge these two buttons to form a single upper image. – m_kiani Nov 06 '13 at 11:34
  • You should have two TouchListener's. One for each button. All of the buttons get the ACTION_DOWN event. But only the one, that has returned true on that gets all other events and can recognize the gesture. I think I see the problem now. Let me edit my answer. I made a mistake. – jboi Nov 06 '13 at 12:16
  • ok, edited. You must check for the right triangle directly in `onTouch`. – jboi Nov 06 '13 at 12:38
  • you are not getting my point, i got clicks on every triangle but now how to combine these two buttons,when i combine them through frame layout click on single button shows popup other button is not showing toast. – m_kiani Nov 07 '13 at 07:29
  • i have edited the code again,they work separately fine but in frame layout only click on button 1 is showing toast. – m_kiani Nov 07 '13 at 07:44
  • Hmmmm, how can I send you my test code? It has about 270 lines of Java and about 50 lines of XML (It shows and tests a bit more then this case). You could use this as a template and delete what you dont need. The code has two touchable areas, one over the other in a FrameLayout. Both have TouchListener implemented and recognize if the touch/click happened on the upper or lower area depending if the touch was in the upper, left triangle or lower, right one. – jboi Nov 07 '13 at 11:47
  • kindly email me mujtba.k@gmail.com – m_kiani Nov 08 '13 at 12:13
  • @jboi, I'm having a similar issue I think. Can you take a look at this question please: http://stackoverflow.com/questions/20777887/custom-view-with-buttons. – amp Dec 29 '13 at 19:26