How to manage a MotionEvent going from one View to another?

Posted by Darren on Stack Overflow See other posts from Stack Overflow or by Darren
Published on 2010-04-10T20:27:52Z Indexed on 2010/04/10 20:33 UTC
Read the original article Hit count: 405

I have a SurfaceView that takes up part of the screen, and some buttons along the bottom. When a button is pressed and the user drags, I want to be able to drag a picture (based on the button) onto the SurfaceView and have it drawn there.

I want to be able to use clickListeners and the like, and not just have a giant SurfaceView with me writing code to detect where the user pressed and if it's a button, etc.

I have somewhat of a solution, but it seems a bit of a hack to me. What is the best way to accomplish this using the framework intelligently?

Part of my XML:

<RelativeLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/background">

<!-- Place buttons along the bottom -->
<RelativeLayout android:id="@+id/bottom_bar"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="40dip"
    android:layout_alignParentBottom="true"
    android:background="@null">

    <ImageButton android:id="@+id/btn_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:background="@null"
        android:src="@drawable/btn_1">
    </ImageButton>

    <!-- More buttons here... -->
</RelativeLayout>

 <!-- Place the SurfaceView in a frame so we can stack on top of it -->
<FrameLayout
    android:layout_width="fill_parent"
    android:layout_height="0px"
    android:layout_weight="1"
    android:layout_above="@id/bottom_bar">

    <com.project.question.MySurfaceView
        android:id="@+id/my_view"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
    />
</FrameLayout>

And the relevant Java code in MySurfaceView, which extends SurfaceView. mTouchX and Y are used in the onDraw method to draw the image:

@Override
public boolean onTouchEvent(MotionEvent event){
    mTouchX = (int) event.getX();
    mTouchY = (int) event.getY();
    return true;
}

public void onButtonTouchEvent(MotionEvent event){
    event.setLocation(event.getX(), event.getY() + mScreenHeight);
    onTouchEvent(event);
}

Finally, the activity:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.my_surface);

    mView = (MySurfaceView) findViewById(R.id.my_view);
    mSurfaceHeight = mView.getHeight();
    mBtn = (ImageButton) findViewById(R.id.btn_1);
    mBtn.setOnTouchListener(mTouchListener);
}

OnTouchListener mTouchListener = new OnTouchListener() {
    public boolean onTouch(View v, MotionEvent event) {
        int [] location = new int[2];
        v.getLocationOnScreen(location);
        event.setLocation(event.getX() + location[0], event.getY());
        mView.onButtonTouchEvent(event);
        return true;
    }
};

Strangely, one has to add to the x-coordinate in the activity, then add to the y coordinate in the View. Otherwise, it doesn't show up in the correct position. If you add nothing, something drawn using mTouchX and mTouchY will show up in the upper left corner of the SurfaceView.

Any direction would be greatly appreciated. If I'm going about this completely the wrong way, that would be good information too.

© Stack Overflow or respective owner

Related posts about android

Related posts about android-layout