简体   繁体   中英

Android - onTouchListener not working for child LinearLayout

I am trying to get swipe up/down gesture. Question is not about how to implement swipe up/down catch. I can not catch onTouch call. Inside of Fragment layout, there is LinearLayout for which has been set onTouchListener. But somehow it is not working - can not get onTouch call.

This is that LinearLayout:

    <LinearLayout
        android:id="@+id/llContent"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <Button
            android:id="@+id/btn_back"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@android:color/transparent" />

        <Button
            android:id="@+id/btn_forward"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@android:color/transparent" />

    </LinearLayout>

This is how Component tree for Fragment layout: 在此处输入图片说明

Inside Fragment's onCreateView, I am setting onTouchListener to that LinearLayout:

    LinearLayout llContent = (LinearLayout) view.findViewById(R.id.llContent);
    llContent.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            new MyLog("Touch");
            return true;
        }

    });

I thought, this is because of child button and clickListeners. So I disabled them:

//        view.findViewById(R.id.btn_back).setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View v) {
//                mCurrentIndex = (mCurrentIndex > 0) ? mCurrentIndex - 1 : 0;
//                update();
//            }
//        });
//        view.findViewById(R.id.btn_forward).setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View v) {
//                mCurrentIndex = (mCurrentIndex < mPagination.size() - 1) ? mCurrentIndex + 1 : mPagination.size() - 1;
//                update();
//            }
//        });

On StackOverflow, there are a lot of questions regarding this and there are solutions.

Try 1: This answer says that I should return true from onTouch method. My onTouch method already returns true.

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        new MyLog("Touch");
        return true;
    }

Try 2: This answer says that I should override onTouchListener's onTouchEvent method. But when I implemented onTouchListener interface, I could not override onTouchEvent. Android Studio's intellisense could not find. When I written it manually, Android Studio shown onTouchEvent method as error. Error: Method does not override method from its superclass . Same answer is here too.

Question: How to get onTouch call for child LinearLayout?

This is XML for whole fragment layout:

<?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:background="#FEFFFF">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <HorizontalScrollView
            android:layout_width="match_parent"
            android:layout_height="41dp"
            android:background="#EFF0F1"
            android:scrollbars="none">

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:gravity="center_vertical"
                android:orientation="horizontal"
                android:paddingLeft="57dp"
                android:paddingRight="57dp">

                <TextView
                    android:id="@+id/tvTitle"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textColor="#2E2F30"
                    android:textSize="17sp" />

                <TextView
                    android:id="@+id/tvAuthor"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="5dp"
                    android:textColor="#5E5F60"
                    android:textSize="17dp" />

            </LinearLayout>

        </HorizontalScrollView>

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

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical"
                android:paddingBottom="8dp"
                android:paddingLeft="25dp"
                android:paddingRight="25dp"
                android:paddingTop="8dp">

                <TextView
                    android:id="@+id/tv"
                    android:layout_width="match_parent"
                    android:layout_height="0dp"
                    android:layout_weight="1"
                    android:textColor="#1C1D1D"
                    android:textSize="18sp" />

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="24dp"
                    android:orientation="vertical">

                    <View
                        android:layout_width="match_parent"
                        android:layout_height="1dp"
                        android:background="#050505" />

                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="8dp"
                        android:orientation="horizontal">

                        <TextView
                            android:id="@+id/tvPercent"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_marginRight="10dp"
                            android:textSize="15sp" />

                        <TextView
                            android:id="@+id/tvProgress"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:textColor="#444546"
                            android:textSize="15sp" />

                    </LinearLayout>

                </LinearLayout>

            </LinearLayout>

            <LinearLayout
                android:id="@+id/llContent"
                android:layout_width="match_parent"
                android:layout_height="match_parent">

                <Button
                    android:id="@+id/btn_back"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:background="@android:color/transparent" />

                <Button
                    android:id="@+id/btn_forward"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:background="@android:color/transparent" />

            </LinearLayout>


        </RelativeLayout>

    </LinearLayout>

</RelativeLayout>

Try this:

 LinearLayout llContent = (LinearLayout) view.findViewById(R.id.llContent);
        llContent.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                Log.d(TAG, "onTouch");
                return true;
            }

        });

        Button ff = (Button)view.findViewById(R.id.btn_forward);
        ff.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                Log.i(TAG, "onTouch");
                return false;

            }
        });

        ff.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Log.i(TAG, "onClick");
            }
        });

The btn_forward is above llContent , therefore you need to return false in onTouch() ( btn_forward ). Then the event will be called from bottom control ( llContent ).

Set android:clickable="false" and android:focusable="false" on your buttons.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM