Search code examples
javaandroidandroid-activityandroid-scrollview

Why I can't detect a swipe inside of a scrollview?


I have this in my 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=".MainActivity" >

    <ImageView
        android:id="@+id/jokeIcon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:contentDescription="@string/app_name"
        />

    <ScrollView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_below="@+id/jokeIcon" >

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >

            <TextView
                android:id="@+id/allJokesTxt"
                style="?android:textAppearanceMedium"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:gravity="center"
                android:lineSpacingMultiplier="1.2"
                android:padding="16dp" />

        </LinearLayout>
    </ScrollView>

</RelativeLayout>

and this code in my activity:

public boolean onTouchEvent(MotionEvent event) {

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                x1 = event.getX();
                break;
            case MotionEvent.ACTION_UP:
                x2 = event.getX();
                float deltaX = x2 - x1;

                if (Math.abs(deltaX) > MIN_DISTANCE) {
                    changeText();

                } else {
                    // consider as something else - a screen tap for example
                }
                break;
        }
        return super.onTouchEvent(event);
    }


 private void changeText(){
    // Left to Right swipe action
    if (x2 > x1) {
        if (jokesCounter > 0) {
            --jokesCounter;
            currentJoke.setVisibility(View.VISIBLE);
            currentJoke.setText(jokesCollector.get(jokesCounter));
        } else {
            Context context = getApplicationContext();
            CharSequence text = "xxx";
            int duration = Toast.LENGTH_SHORT;

            Toast toast = Toast.makeText(context, text, duration);
            toast.show();
        }

    }

    // Right to left swipe action
    else {
        if (jokesLengthCounter >= jokesCounter) {
            ++jokesCounter;

            currentJoke.setVisibility(View.VISIBLE);
            currentJoke.setText(jokesCollector.get(jokesCounter));
        } else {
            Context context = getApplicationContext();
            CharSequence text = "xxx";
            int duration = Toast.LENGTH_SHORT;

            Toast toast = Toast.makeText(context, text, duration);
            toast.show();
        }

    }

}

Now this is supposed the change the text on the screen when the users swipes left to right, or the oposite way. The problem is that the swipe is detected only when it is done on the ìmageView, I mean that a swipe inside of the ScrollView(on the actual textView) is not detected at all.

Why is that happening? I know that I;m missing an extremely small part here, but I'm not able to spot it at the moment. Can you give me a push?


Solution

  • you have to override onInterceptTouchEvent for scrollview it allows you to pass touch events to its child views

    You can ref: ScrollView with children view, how to intercept scroll conditionally

    ref: http://developer.android.com/reference/android/view/ViewGroup.html#onInterceptTouchEvent%28android.view.MotionEvent%29