Борьба с onTouchListener - PullRequest
       38

Борьба с onTouchListener

1 голос
/ 07 марта 2019

У меня есть ViewFlipper, на котором я хочу установить touchListener.Он находится внутри ScrollView (под ViewFlipper есть больше элементов пользовательского интерфейса), и я хочу, чтобы, если пользователь делает вертикальное движение, scrollview действует, а когда пользователь делает горизонтальное движение, ViewFlipper действует.(Компоненты добавляются динамически в ViewFlipper).

Для пояснения, это макет:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/parentrl">



<ScrollView
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <ViewFlipper
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/vflipper"
            android:layout_marginStart="20dp"
            android:layout_marginEnd="20dp"
            android:layout_marginTop="20dp"
            android:background="@drawable/flightcomponentborder">


        </ViewFlipper>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/inforecogida"
            android:layout_marginStart="10dp"
            android:layout_marginTop="10dp"
            android:text="@string/inforecogida"
            android:textColor="@color/actionbardefaultcolor"
            android:layout_below="@+id/vflipper"/>

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="2dp"
            android:layout_below="@+id/inforecogida"
            android:id="@+id/separador"
            android:background="@color/gris"
            android:layout_marginTop="10dp"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/personaheader"
            android:layout_below="@+id/separador"
            android:layout_marginTop="10dp"
            android:layout_alignStart="@+id/inforecogida"
            android:text="@string/persona"
            android:textColor="@color/actionbardefaultcolor"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/persona"
            android:layout_below="@+id/personaheader"
            android:layout_alignStart="@+id/inforecogida"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/infotext"
            android:layout_alignStart="@+id/inforecogida"
            android:layout_below="@+id/persona"
            android:text="@string/infotext"
            android:textStyle="italic"/>

    </RelativeLayout>

</ScrollView>



</RelativeLayout>

Это TouchListener, который я добавляю в ViewFlipper:

parentListener = new View.OnTouchListener(){
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            int action = event.getActionMasked();
            switch (action) {
                case MotionEvent.ACTION_DOWN:
                    startX = event.getX();
                    startY = event.getRawY();

                    break;


                case MotionEvent.ACTION_UP:

                    endX = event.getX();
                    endY = event.getRawY();
                    int movX;//0=swipe izq 1=swipe right
                    int movY;
                    if(startX-endX < 0){
                        movX=0;
                        Log.i("David", "Swipe left action up");
                        float totalPixelsX=Math.abs(startX-endX);
                        float totalPixelsY=event.getRawY() - startY;
                        Log.i("David", "totalPixelsx: "+totalPixelsX);
                        Log.i("David", "totalPixelsY: "+totalPixelsY);
                        if(totalPixelsY<0){
                            Log.i("David", "scroll down");
                            totalPixelsY=event.getRawY() - startY;
                            Log.i("David", "We moved "+totalPixelsY+" pixels");
                        }else{
                            Log.i("David", "scroll up");
                            Log.i("David", "We moved "+totalPixelsY+" pixels");
                        }
                    }else{
                        movX=1;
                        Log.i("David", "Swipe right action up");
                        float totalPixelsX=Math.abs(startX-endX);
                        float totalPixelsY=event.getRawY() - startY;
                        Log.i("David", "totalPixelsx: "+totalPixelsX);
                        Log.i("David", "totalPixelsY: "+totalPixelsY);
                        if(totalPixelsY<0){
                            Log.i("David", "scroll down");
                            totalPixelsY=event.getRawY() - startY;
                            Log.i("David", "We moved "+totalPixelsY+" pixels");
                        }else{
                            Log.i("David", "scroll up");
                            Log.i("David", "We moved "+totalPixelsY+" pixels");
                        }
                    }
                    Log.i("David", "haveFlipped false");
                    haveFlipped=false;
                    break;

                case MotionEvent.ACTION_CANCEL:
                    endX = event.getX();
                    endY = event.getRawY();
                    if(startX-endX < 0){
                        movX=0;
                        Log.i("David", "Swipe left action cancel");
                        float totalPixelsX=Math.abs(startX-endX);
                        float totalPixelsY=event.getRawY() - startY;
                        Log.i("David", "totalPixelsx: "+totalPixelsX);
                        Log.i("David", "totalPixelsY: "+totalPixelsY);
                        if(totalPixelsY<0){
                            Log.i("David", "scroll down");
                            totalPixelsY=event.getRawY() - startY;
                            Log.i("David", "We moved "+totalPixelsY+" pixels");
                        }else{
                            Log.i("David", "scroll up");
                            Log.i("David", "We moved "+totalPixelsY+" pixels");
                        }
                    }else{
                        movX=1;
                        Log.i("David", "Swipe right action cancel");
                        float totalPixelsX=Math.abs(startX-endX);
                        float totalPixelsY=event.getRawY() - startY;
                        Log.i("David", "totalPixelsx: "+totalPixelsX);
                        Log.i("David", "totalPixelsY: "+totalPixelsY);
                        if(totalPixelsY<0){
                            Log.i("David", "scroll down");
                            totalPixelsY=event.getRawY() - startY;
                            Log.i("David", "We moved "+totalPixelsY+" pixels");
                        }else{
                            Log.i("David", "scroll up");
                        }
                    }
                    Log.i("David", "haveFlipped false");
                    haveFlipped=false;
                    break;

            }
            return true;
        }
    };

Моя проблема в том, что action_cancel или action_up называются ДО того, как мой палец поднимется с экрана телефона, поэтому величина движения по оси Y всегда меньше, чем фактическое движение моего пальца.

Что яПлан состоит в том, чтобы, когда величина X> сумма y, использовать ViewFlipper, а когда сумма X <сумма y, оставьте ScrollView делать свою работу. </p>

Я не знаю, еслимой подход правильный.Кто-нибудь может сказать, почему вызывается action_up и action_cancel, прежде чем я подниму палец?А как достичь своей цели?

Спасибо.

Ответы [ 2 ]

0 голосов
/ 07 марта 2019

Мне удалось заставить его работать, удалив эти строки из MotionEvent.ACTION_CANCEL и MotionEvent.ACTION_UP:

endX = event.getX();
endY = event.getRawY();

И затем, добавив это на коммутаторе:

case MotionEvent.ACTION_MOVE:
endX = event.getX();
endY = event.getRawY();
break;

ThisКстати, ScrollView и ViewFlipper работают так, как должны.

0 голосов
/ 07 марта 2019

Если ViewFlipper возвращает TRUE в своем методе onTouch (), тогда единственный способ - создать новый класс, расширяющий RelativeLayout, и реализовать его метод onInterceptTouchEvent ().

public class MyRelativeLayout extends RelativeLayout {
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return super.onInterceptTouchEvent(ev);
    }
}

Затем используйте этот MyRelativeLayout в качестве корня файла макета XML.

...