OnTouchListener во фрагменте

У меня есть этот макет в моем фрагменте:

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


<android.support.design.widget.FloatingActionButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:clickable="true"
    app:fabSize="mini"
    app:srcCompat="@android:drawable/btn_default"
    android:id="@+id/floatingActionButton"
    android:layout_alignParentRight="true"
    android:layout_alignParentEnd="true"
    android:layout_alignParentBottom="true" />

<Button
    android:text="@string/next"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:id="@+id/button"
    android:layout_alignParentStart="true"
    android:layout_alignParentLeft="true"
    android:layout_toStartOf="@+id/floatingActionButton"
    android:layout_toLeftOf="@+id/floatingActionButton"/>



    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/sv"
        android:layout_alignParentTop="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentLeft="true"
        android:layout_above="@+id/button">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/relativelayoutglobal"
            android:orientation="vertical">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/relativelayoutobligatorios"
                android:orientation="vertical">


                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:textAppearance="?android:attr/textAppearanceLarge"
                    android:text="@string/obligatorios"
                    android:id="@+id/textViewirgeneral"
                    android:background="@color/naranja"
                    android:layout_marginTop="15dp"/>

                <ImageView
                    android:layout_width="match_parent"
                    android:layout_height="2dp"
                    android:id="@+id/imageViewirgeneral"
                    android:background="@color/black" />

                //Here are some textinputlayout

            </LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/relativelayoutgeneral"
                android:orientation="vertical">

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:textAppearance="?android:attr/textAppearanceLarge"
                    android:text="@string/general"
                    android:id="@+id/textViewiugeneral"
                    android:background="@color/naranja"
                    android:layout_marginTop="15dp"/>

                <ImageView
                    android:layout_width="match_parent"
                    android:layout_height="2dp"
                    android:id="@+id/imageViewiugeneral"
                    android:background="@color/black" />

            </LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/relativelayoutsuelo"
                android:orientation="vertical">

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:textAppearance="?android:attr/textAppearanceLarge"
                    android:text="@string/suelo"
                    android:id="@+id/textViewiusuelo"
                    android:background="@color/naranja"
                    android:layout_marginTop="15dp"/>

                <ImageView
                    android:layout_width="match_parent"
                    android:layout_height="2dp"
                    android:id="@+id/imageViewiusuelo"
                    android:background="@color/black" />

            </LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/relativelayoutcon"
                android:orientation="vertical">

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:textAppearance="?android:attr/textAppearanceLarge"
                    android:text="@string/construccion"
                    android:id="@+id/textViewiucons"
                    android:background="@color/naranja"
                    android:layout_marginTop="15dp"/>

                <ImageView
                    android:layout_width="match_parent"
                    android:layout_height="2dp"
                    android:id="@+id/imageViewiucons"
                    android:background="@color/black" />

            </LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/relativelayoutcomp"
                android:orientation="vertical">

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:textAppearance="?android:attr/textAppearanceLarge"
                    android:text="@string/inmueblecompleto"
                    android:id="@+id/textViewiucomp"
                    android:background="@color/naranja"
                    android:layout_marginTop="15dp"/>

                <ImageView
                    android:layout_width="match_parent"
                    android:layout_height="2dp"
                    android:id="@+id/imageViewiucomp"
                    android:background="@color/black" />

            </LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/relativelayoutamort"
                android:orientation="vertical">

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:textAppearance="?android:attr/textAppearanceLarge"
                    android:text="@string/amortizaciones"
                    android:id="@+id/textViewiuamort"
                    android:background="@color/naranja"
                    android:layout_marginTop="15dp"/>

                <ImageView
                    android:layout_width="match_parent"
                    android:layout_height="2dp"
                    android:id="@+id/imageViewiuamort"
                    android:background="@color/black" />

            </LinearLayout>

        </LinearLayout>

    </ScrollView>

Мне нужно отреагировать на пользователя, проводящего пальцем вправо или влево, поэтому во фрагменте, который использует этот макет, я реализовал View.OnTouchListener и переопределил метод OnTouch:

@Override
public boolean onTouch(View v, MotionEvent event) {

    if(!touching){
        Log.i("TAG", "onTouch llamado");

        int action = event.getActionMasked();

        switch (action) {

            case MotionEvent.ACTION_DOWN:
                initialX = event.getX();
                initialY = event.getY();
                Log.d("TAG", "Action was DOWN");

                break;

            case MotionEvent.ACTION_UP:
                float finalX = event.getX();
                float finalY = event.getY();

                Log.d("TAG", "Action was UP");

                if (initialX < finalX) {
                    Log.d("TAG", "Left to Right swipe performed");
                }

                if (initialX > finalX) {
                    Log.d("TAG", "Right to Left swipe performed");
                    validate();
                }

                if (initialY < finalY) {
                    Log.d("TAG", "Up to Down swipe performed");
                }

                if (initialY > finalY) {
                    Log.d("TAG", "Down to Up swipe performed");
                }

                initialX=0F;
                initialY=0F;
                finalX=0F;
                finalY=0F;

                break;

            case MotionEvent.ACTION_CANCEL:
                Log.d("TAG","Action was CANCEL");
                break;

            case MotionEvent.ACTION_OUTSIDE:
                Log.d("TAG", "Movement occurred outside bounds of current screen element");
                break;
        }
        return true;
    }else{
        return false;
    }

}

Таким образом, метод OnTouch не вызывается. Я попытался установить OnTouchListener в каждом из различных LinearLayout моего xml, и таким образом вызывается метод OnTouch, пока я не касаюсь пространства, где находится другой компонент (например, TextInputLayout). Я бы хотел, чтобы OnTouch вызывался повсюду в родительском макете, но все еще мог использовать TextInputLayout. Я попытался установить onTouchListener для TextInputLayouts, но затем они перестают работать, как предполагалось, и действуют, как будто они не были включены.

Я хотел бы избежать использования ViewPager, потому что у меня есть много функций, которые должны быть изменены, если мне нужно использовать этот компонент.

Как я могу заставить весь макет реагировать на OnTouch, сохраняя TextInputLayout работающим?

Спасибо.

1 ответ

Вы можете setOnTouchListener() на вид, который вы надули в своем фрагменте. Это обеспечит onTouch() вызывается всякий раз, когда пользователь касается фрагмента. Чтобы включить ваш TextInputLayoutВы можете продлить TextInputLayout сделать собственный класс, переопределить onTouchEvent в нем вызовите super и верните true, как показано ниже.

public class MyTextInputLayout extends TextInputLayout {

    public MyTextInputLayout(Context context) {
        super(context);
    }

    public MyTextInputLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyTextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);

        return true;
    }
}

Затем вы будете использовать MyTextInputLayout вместо TextInputLayout в вашем макете XML или везде, где вы его раздули. Это предотвратит передачу события прикосновения к фрагменту, когда пользователь коснется вашего MyTextInputLayout,

Кроме того, создайте пользовательский класс, расширяющий ViewGroup который находится в корне вашего фрагмента XML, давайте предположим, что это LinearLayout, Класс будет выглядеть так:

public class MyViewGroup extends LinearLayout {
    public MyViewGroup(Context context) {
        super(context);
    }

    public MyViewGroup(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public MyViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public MyViewGroup(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        View myTextInputLayout = findViewById(R.id.my_text_input_layout); // Replace with your resource ID

        if (myTextInputLayout != null) {
            Rect rect = new Rect();
            myTextInputLayout.getHitRect(rect);

            if (rect.contains(rect)) {
                return false;
            }
        }

        return super.onInterceptTouchEvent(ev);
    }
}

И вы, очевидно, будете использовать вышеупомянутый класс вместо LinearLayout в вашем XML.

Другие вопросы по тегам