Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Split motion events - accept inputs to multiple views simultaneosly

I'm trying to get split touch events working, this means being able to detect touch input separately in multiple views.

It was a feature added to honeycomb and can be backported using the compatibility library. There is more info here: http://developer.android.com/sdk/android-3.0.html ->Scroll down to "split touch events"

It basically says: Previously, only a single view could accept touch events at one time. Android 3.0 adds support for splitting touch events across views and even windows, so different views can accept simultaneous touch events. Split touch events is enabled by default when an application targets Android 3.0. That is, when the application has set either the android:minSdkVersion or android:targetSdkVersion attribute's value to "11".

Here is a sample project I am using to test it: https://sites.google.com/site/droidbean/hologramlwp/downloadmodels/attachments/SplitMotionTest.rar?attredirects=0&d=1

In the project there are 2 imageviews, touching the top one produces Log.e events with a tag of 'pointer' while the bottom view produces 'pointer2' but as you can see touching the top view and then the 2nd with a separate finger (both are touching separate views) produces only messages from the first view in gingerbread.

If the same project is run on honeycomb, it works correctly and both views produce their respective 'pointer' log entries.

So my question would be, how do I get this same effect on a phone running gingerbread or any other lower android version?

like image 383
behelit Avatar asked Jan 11 '12 09:01

behelit


1 Answers

Since Gingerbread doesn't support splitting touch events, one solution would be to create an overlay over the two views. e.g. add an empty RelativeLayout after the other views in the xml or in code that covers the two views, let's call it the overlay. Set the overlay's OnTouchListener and programmatically determine which view the event occured (x,y). Then send the event through to the determined view's onTouchEvent.

This is not very friendly, that's why they fixed it.

Example:

    public boolean onTouch(View v, MotionEvent event)
    {
        if(view1.hitTest(event)) 
        {
            return view1.onTouchEvent(event);
        } else if(view2.hitTest(event)) 
        {
            return view2.onTouchEvent(event);
        }
        return false;
    }
like image 115
beplaya Avatar answered Oct 27 '22 00:10

beplaya