cardview onTouch监听器冲突/灵敏度中的android listview

标签 android android-layout listview ontouchlistener android-cardview

这是一个显示问题保管箱链接的测试项目: https://www.dropbox.com/sh/8s3v9ydcj6jvpl8/AACZ2VRP2N9R1ec7pxrsAn0ga?dl=0

这是我在这里回答的问题的延续,但现在我要问的是 onTouch 的敏感性/冲突: Android CardView with ListView inside - onTouchListener on CardView not working

我有一个卡片 View ,里面有一个 ListView 。我也需要滚动并单击 ListView 中的项目才能工作,我也希望能够使用 ontouchlistener 移动整个 cardview。 我在 cardview 上设置了一个 onTouchListener,但它不能正常工作,因为 listview 滚动与 cardview 移动冲突。

我已经能够让类似的东西在 iOS 上完美运行,因此在 Android 上也应该可行。

代码:

将其放入 build.gradle 中:

compile 'com.android.support:cardview-v7:22.0+'

主要 Activity :

    import android.animation.Animator;
import android.graphics.PointF;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.CardView;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.RelativeLayout;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private ListView mylistview;
    private CustomCardView mycardview;
    PointF lastLocation;
    static final int REFRESH_RATE = 10; //or 20, or 5, or 30, whatever works best
    int counter = 0;
    PointF viewCenter;
    PointF cardOriginalLocation;
    boolean checkIfPanning;
    RelativeLayout layout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        layout = (RelativeLayout)findViewById(R.id.layout);
        mycardview = (CustomCardView)findViewById(R.id.mycardview);
        mylistview = (ListView) findViewById(R.id.myListView);

        List<String> your_array_list = new ArrayList<String>();
        your_array_list.add("foo");
        your_array_list.add("bar");
        your_array_list.add("foo");
        your_array_list.add("bar");
        your_array_list.add("foo");
        your_array_list.add("bar");
        your_array_list.add("foo");
        your_array_list.add("bar");
        your_array_list.add("foo");
        your_array_list.add("bar");
        your_array_list.add("foo");
        your_array_list.add("bar");
        your_array_list.add("foo");
        your_array_list.add("bar");


        ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,your_array_list );

        mylistview.setAdapter(arrayAdapter);
        mycardview.setCardElevation(20);



        mycardview.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                mycardview.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                cardOriginalLocation = new PointF(mycardview.getX(), mycardview.getY());
                viewCenter = new PointF(layout.getWidth() / 2, layout.getHeight() / 2);
            }
        });


        View.OnTouchListener onTouchListener = new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {


                if(mylistview!=null){
                    //Route all touch event to listview without logic
                    System.out.println("AAAAAA Touched list");
                    mylistview.onTouchEvent(event);

                }

                if (event.getAction()==MotionEvent.ACTION_DOWN){
                    System.out.println("ACTION_DOWN");

                    checkIfPanning=true;

                    lastLocation = new PointF(event.getRawX(),event.getRawY());
                    return true;
                } else if (checkIfPanning && event.getAction()==MotionEvent.ACTION_MOVE/* && (getFrontCard().getX() - (lastLocation.x - event.getRawX()))<=10*/){
                    System.out.println("ACTION_MOVE");

                    counter += 1;

                    if((REFRESH_RATE % counter) == 0) {


                        float newx = mycardview.getX() - (lastLocation.x - event.getRawX());



                        float newy = mycardview.getY() - (lastLocation.y - event.getRawY());

                        mycardview.setX(newx);
                        mycardview.setY(newy);

                        lastLocation.set(event.getRawX(), event.getRawY());


                        float completedPercent = Math.min(((mycardview.getX() + mycardview.getWidth() / 2) - viewCenter.x) / viewCenter.x, 1);
                        float angle =  (completedPercent*15);
                        mycardview.setRotation(angle);
                    }
                    counter=0;
                    return true;
                } else if (event.getAction()==MotionEvent.ACTION_UP){


                    System.out.println("ACTION_UP");

                    checkIfPanning=false;

                    float displaceentFromCenterX = ((mycardview.getX()+mycardview.getWidth()/2) - viewCenter.x);

                    if (Math.abs(displaceentFromCenterX)>225){
                        float toMove;
                        if (displaceentFromCenterX>0){
                            toMove = layout.getWidth()+mycardview.getHeight();
                        } else {
                            toMove = -mycardview.getWidth()-mycardview.getHeight();
                        }

                        mycardview.animate().rotationBy(30).translationX(toMove).setDuration(100).setListener(new Animator.AnimatorListener() {
                            @Override
                            public void onAnimationStart(Animator animation) {
                                System.out.println("onAnimationStart");
                            }

                            @Override
                            public void onAnimationEnd(Animator animation) {
                                animation.removeListener(this);
                                System.out.println("DONNNNNE");
                                mycardview.setX(cardOriginalLocation.x);
                                mycardview.setY(cardOriginalLocation.y);
                                mycardview.setRotation(0);

                            }

                            @Override
                            public void onAnimationCancel(Animator animation) {

                            }

                            @Override
                            public void onAnimationRepeat(Animator animation) {

                            }
                        });
                    } else {


                        mycardview.animate().rotation(0).translationX(0).translationY(0).setDuration(100).setListener(new Animator.AnimatorListener() {
                            @Override
                            public void onAnimationStart(Animator animation) {

                            }

                            @Override
                            public void onAnimationEnd(Animator animation) {

                            }

                            @Override
                            public void onAnimationCancel(Animator animation) {

                            }

                            @Override
                            public void onAnimationRepeat(Animator animation) {

                            }
                        });
                    }


                    return true;
                } else {
                    checkIfPanning=false;
                    if(mylistview!=null){
                        //Route all touch event to listview without logic
                        System.out.println("BBBBB Touched list");
                        mylistview.onTouchEvent(event);
                        return true;
                    }
                }
                return true;
            }


        };

        mycardview.setOnTouchListener(onTouchListener);

    }
}

cardview onTouch 监听器和 listview 现在都检测到触摸。但是,当我尝试移动卡片 View 时, ListView 一直在尝试滚动。当我尝试在列表上滚动时,卡片反而移动了。

我明白为什么会这样。基本上,onTouch 监听器似乎将 cardview 移动与 listview 滚动相冲突,但我不确定如何在代码中弄清楚我是在尝试滚动还是移动 cardview。

MainActivity 的 XML:

    <?xml version="1.0" encoding="utf-8"?>
<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="com.pranapps.testontouch.MainActivity"
    android:id="@+id/layout"
    >



<com.pranapps.testontouch.CustomCardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_gravity="center"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:id="@+id/mycardview"
    card_view:cardUseCompatPadding="true">

    <ListView
        android:layout_width="match_parent"
        android:layout_height="fill_parent"
        android:id="@+id/myListView"
        android:dividerHeight="0.2dp"
        android:overScrollMode="always"
        android:smoothScrollbar="true"
        android:groupIndicator="@null"
        ></ListView>



</com.pranapps.testontouch.CustomCardView>

</RelativeLayout>

自定义卡片 View 代码:

package com.pranapps.testontouch;

import android.content.Context;
import android.support.v7.widget.CardView;
import android.util.AttributeSet;
import android.view.MotionEvent;

/**
 * Created by pranoychowdhury on 5/9/16.
 */
public class CustomCardView extends CardView {
    public CustomCardView(Context context) {
        super(context);
    }

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

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

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        /*
        * This method determines whether we want to intercept the motion.
        * If we return true, onTouchEvent will be called.
        */
        System.out.println("Touched custom from card");
        return true;
    }
}

请大家帮忙推荐试试! 谢谢!

编辑:这是一段视频,介绍它在 iOS 上的工作原理。我可以在 ListView 上滚动。向左或向右平移会使卡片移动。 https://www.dropbox.com/s/5dm52vtjb1xgcl5/iOS.mov?dl=0

卡片 View 不会滚动,只有卡片 View (即 ListView )内的内容会滚动。卡片 View 只能通过跟踪手指来回移动。想象一下 tinder,您可以在其中刷卡并在卡内滚动。

最佳答案

经过 2 周的试验,我自己解决了这个问题。

我从卡片 View 中删除了 onInterceptTouchEvent 和 ontouch。相反,创建一个自定义 OnTouchListener 并将其附加到 ListView 本身。然后在自定义的 OnTouchListener 中,尝试找出触摸发生的角度。如果角度在特定范围内,则向上或向下滚动。其他明智的左/右滑动。我仍在尝试校准角度,以确定哪个角度最适合可用性,但这似乎工作得很好。

我从这个链接中得到了一些计算角度的帮助: How to detect swipe direction between left/right and up/down

解决方案:

主要 Activity :

package com.pranapps.testontouch;

import android.animation.Animator;
import android.graphics.PointF;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.CardView;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private ListView mylistview;
    private CustomCardView mycardview;
    PointF lastLocation;
    static final int REFRESH_RATE = 10; //or 20, or 5, or 30, whatever works best
    int counter = 0;
    PointF viewCenter;
    PointF cardOriginalLocation;
    boolean checkIfPanning;
    RelativeLayout layout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        layout = (RelativeLayout)findViewById(R.id.layout);
        mycardview = (CustomCardView)findViewById(R.id.mycardview);
        mylistview = (ListView) findViewById(R.id.myListView);

        List<String> your_array_list = new ArrayList<String>();
        your_array_list.add("foo");
        your_array_list.add("bar");
        your_array_list.add("foo");
        your_array_list.add("bar");
        your_array_list.add("foo");
        your_array_list.add("bar");
        your_array_list.add("foo");
        your_array_list.add("bar");
        your_array_list.add("foo");
        your_array_list.add("bar");
        your_array_list.add("foo");
        your_array_list.add("bar");
        your_array_list.add("foo");
        your_array_list.add("bar");


        ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,your_array_list );

        mylistview.setAdapter(arrayAdapter);
        mycardview.setCardElevation(20);



        mycardview.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                mycardview.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                cardOriginalLocation = new PointF(mycardview.getX(), mycardview.getY());
                viewCenter = new PointF(layout.getWidth() / 2, layout.getHeight() / 2);
            }
        });


        mylistview.setOnTouchListener(new OnSwipeTouchListener(){

            @Override
            public void onSwipeStart(MotionEvent motionEvent) {
                super.onSwipeStart(motionEvent);
                System.out.println("Swipe Start");
                checkIfPanning=true;
                //if (lastLocation==null) {
                    lastLocation = new PointF(motionEvent.getRawX(),motionEvent.getRawY());
                //}
            }

            @Override
            public void onSwipeEnd(MotionEvent motionEvent) {
                super.onSwipeEnd(motionEvent);

                System.out.println("Swipe End");

                checkIfPanning=false;

                float displaceentFromCenterX = ((mycardview.getX()+mycardview.getWidth()/2) - viewCenter.x);

                if (Math.abs(displaceentFromCenterX)>225){
                    float toMove;
                    if (displaceentFromCenterX>0){
                        toMove = layout.getWidth()+mycardview.getHeight();
                    } else {
                        toMove = -mycardview.getWidth()-mycardview.getHeight();
                    }

                    mycardview.animate().rotationBy(30).translationX(toMove).setDuration(100).setListener(new Animator.AnimatorListener() {
                        @Override
                        public void onAnimationStart(Animator animation) {
                            System.out.println("onAnimationStart");
                        }

                        @Override
                        public void onAnimationEnd(Animator animation) {
                            animation.removeListener(this);
                            System.out.println("DONNNNNE");
                            mycardview.setX(cardOriginalLocation.x);
                            mycardview.setY(cardOriginalLocation.y);
                            mycardview.setRotation(0);

                        }

                        @Override
                        public void onAnimationCancel(Animator animation) {

                        }

                        @Override
                        public void onAnimationRepeat(Animator animation) {

                        }
                    });
                } else {


                    mycardview.animate().rotation(0).translationX(0).translationY(0).setDuration(100).setListener(new Animator.AnimatorListener() {
                        @Override
                        public void onAnimationStart(Animator animation) {

                        }

                        @Override
                        public void onAnimationEnd(Animator animation) {

                        }

                        @Override
                        public void onAnimationCancel(Animator animation) {

                        }

                        @Override
                        public void onAnimationRepeat(Animator animation) {

                        }
                    });
                }
                lastLocation = null;
            }

            @Override
            public void onSwipe(MotionEvent motionEvent) {
                super.onSwipe(motionEvent);
                System.out.println("Swiping");
                counter += 1;

                if((REFRESH_RATE % counter) == 0) {


                    float newx = mycardview.getX() - (lastLocation.x - motionEvent.getRawX());



                    float newy = mycardview.getY() - (lastLocation.y - motionEvent.getRawY());

                    mycardview.setX(newx);
                    mycardview.setY(newy);

                    lastLocation.set(motionEvent.getRawX(), motionEvent.getRawY());


                    float completedPercent = Math.min(((mycardview.getX() + mycardview.getWidth() / 2) - viewCenter.x) / viewCenter.x, 1);
                    float angle =  (completedPercent*15);
                    mycardview.setRotation(angle);
                }
                counter=0;
            }

            @Override
            public void onScroll(MotionEvent motionEvent) {
                super.onSwipe(motionEvent);
                mylistview.onTouchEvent(motionEvent);
            }
        });

        View.OnTouchListener onTouchListener = new View.OnTouchListener() {



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

                System.out.println("ONTOUCHHHH");

                if (event.getAction()==MotionEvent.ACTION_DOWN){
                    System.out.println("ACTION_DOWN");

                    checkIfPanning=true;

                    lastLocation = new PointF(event.getRawX(),event.getRawY());
                    return true;
                } else if (checkIfPanning && event.getAction()==MotionEvent.ACTION_MOVE){
                    System.out.println("ACTION_MOVE");

                    counter += 1;

                    if((REFRESH_RATE % counter) == 0) {


                        float newx = mycardview.getX() - (lastLocation.x - event.getRawX());



                        float newy = mycardview.getY() - (lastLocation.y - event.getRawY());

                        mycardview.setX(newx);
                        mycardview.setY(newy);

                        lastLocation.set(event.getRawX(), event.getRawY());


                        float completedPercent = Math.min(((mycardview.getX() + mycardview.getWidth() / 2) - viewCenter.x) / viewCenter.x, 1);
                        float angle =  (completedPercent*15);
                        mycardview.setRotation(angle);
                    }
                    counter=0;
                    return true;
                } else if (event.getAction()==MotionEvent.ACTION_UP){


                    System.out.println("ACTION_UP");

                    checkIfPanning=false;

                    float displaceentFromCenterX = ((mycardview.getX()+mycardview.getWidth()/2) - viewCenter.x);

                    if (Math.abs(displaceentFromCenterX)>225){
                        float toMove;
                        if (displaceentFromCenterX>0){
                            toMove = layout.getWidth()+mycardview.getHeight();
                        } else {
                            toMove = -mycardview.getWidth()-mycardview.getHeight();
                        }

                        mycardview.animate().rotationBy(30).translationX(toMove).setDuration(100).setListener(new Animator.AnimatorListener() {
                            @Override
                            public void onAnimationStart(Animator animation) {
                                System.out.println("onAnimationStart");
                            }

                            @Override
                            public void onAnimationEnd(Animator animation) {
                                animation.removeListener(this);
                                System.out.println("DONNNNNE");
                                mycardview.setX(cardOriginalLocation.x);
                                mycardview.setY(cardOriginalLocation.y);
                                mycardview.setRotation(0);

                            }

                            @Override
                            public void onAnimationCancel(Animator animation) {

                            }

                            @Override
                            public void onAnimationRepeat(Animator animation) {

                            }
                        });
                    } else {


                        mycardview.animate().rotation(0).translationX(0).translationY(0).setDuration(100).setListener(new Animator.AnimatorListener() {
                            @Override
                            public void onAnimationStart(Animator animation) {

                            }

                            @Override
                            public void onAnimationEnd(Animator animation) {

                            }

                            @Override
                            public void onAnimationCancel(Animator animation) {

                            }

                            @Override
                            public void onAnimationRepeat(Animator animation) {

                            }
                        });
                    }


                    return true;
                }
                return true;
            }


        };

        mycardview.setOnTouchListener(onTouchListener);



    }
}

OnSwipeTouchListener:

package com.pranapps.testontouch;

import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.View.OnTouchListener;


public class OnSwipeTouchListener implements OnTouchListener{


    boolean checkIfStartedTouch;
    boolean checkIfSwiping;
    boolean checkIfScrolling;
    private final GestureDetector gestureDetector = new GestureDetector(new GestureListener());
    private MotionEvent currentEvent;

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

        currentEvent = event;
        if (event.getAction()==MotionEvent.ACTION_DOWN){
            checkIfStartedTouch = true;
        } else if (event.getAction()==MotionEvent.ACTION_UP){
            if (checkIfSwiping){
                onSwipeEnd(event);
            }
            checkIfStartedTouch = false;
            checkIfScrolling = false;
            checkIfSwiping = false;
        } else {
            if (checkIfSwiping){
                //System.out.println("swipe2");
                onSwipe(event);
                return false;
            } if (checkIfScrolling){
                //System.out.println("scroll2");
                onScroll(event);
                return false;
            }
        }

        return gestureDetector.onTouchEvent(event);
    }

    public void onSwipe(MotionEvent motionEvent) {}
    public void onScroll(MotionEvent motionEvent) {}
    public void onSwipeEnd(MotionEvent motionEvent) {}
    public void onSwipeStart(MotionEvent motionEvent) {}

    public enum Direction {
        up,
        down,
        left,
        right;

        /**
         * Returns a direction given an angle.
         * Directions are defined as follows:
         * <p/>
         * 0 is on right side middle (east direction)
         * angle is anticlockwise, 90 is at north pole
         *
         * @param angle an angle from 0 to 360 - e
         * @return the direction of an angle
         */
        public static Direction get(double angle) {
            System.out.println("Angle: "+angle);
            if (inRange(angle, 50, 130)) {
                System.out.println("UPPPPPPPPPP");
                return Direction.up;
            } else if (inRange(angle, 0, 50) || inRange(angle, 310, 360)) {
                System.out.println("RIGHT");
                return Direction.right;
            } else if (inRange(angle, 240, 310)) {
                System.out.println("DOWN");
                return Direction.down;
            } else {
                System.out.println("LEFTT");
                return Direction.left;
            }

        }//i think I have finally figured out an android coding UI problem after 3 weeks. xml files might work for web development but designing decent UIs on a dedicated device using xml files is a nightmare. The fragmentation of device different resolutions makes things even harder.

        /**
         * @param angle an angle
         * @param init  the initial bound
         * @param end   the final bound
         * @return returns true if the given angle is in the interval [init, end).
         */
        private static boolean inRange(double angle, float init, float end) {
            return (angle >= init) && (angle < end);
        }
    }

    private final class GestureListener extends SimpleOnGestureListener {

        @Override
        public boolean onDown(MotionEvent e) {
            return true;
        }

        /*@Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {



            System.out.println("flingggg");
            float x1 = e1.getX();
            float y1 = e1.getY();

            float x2 = e2.getX();
            float y2 = e2.getY();

            Direction direction = getDirection(x1, y1, x2, y2);
            return onSwipe(direction);
        }*/

        @Override
        public boolean onScroll(MotionEvent e1,
                                MotionEvent e2,
                                float distanceX,
                                float distanceY) {

            // Grab two events located on the plane at e1=(x1, y1) and e2=(x2, y2)
            // Let e1 be the initial event
            // e2 can be located at 4 different positions, consider the following diagram
            // (Assume that lines are separated by 90 degrees.)
            //
            //
            //         \ A  /
            //          \  /
            //       D   e1   B
            //          /  \
            //         / C  \
            //
            // So if (x2,y2) falls in region:
            //  A => it's an UP swipe
            //  B => it's a RIGHT swipe
            //  C => it's a DOWN swipe
            //  D => it's a LEFT swipe
            //

            System.out.println("onscrollllll");
            float x1 = e1.getX();
            float y1 = e1.getY();

            float x2 = e2.getX();
            float y2 = e2.getY();

            Direction direction = getDirection(x1, y1, x2, y2);
            return onSwipe(direction);


        }

        public boolean onSwipe(Direction direction) {

            if (direction == Direction.left || direction == Direction.right) {
                System.out.println("swipe");
                if (!checkIfSwiping) {
                    checkIfSwiping = true;
                    onSwipeStart(currentEvent);
                }
                return false;
            }
            else {
                System.out.println("scroll");
                checkIfScrolling=true;
                return true;
            }
        }

        /**
         * Given two points in the plane p1=(x1, x2) and p2=(y1, y1), this method
         * returns the direction that an arrow pointing from p1 to p2 would have.
         *
         * @param x1 the x position of the first point
         * @param y1 the y position of the first point
         * @param x2 the x position of the second point
         * @param y2 the y position of the second point
         * @return the direction
         */
        public Direction getDirection(float x1, float y1, float x2, float y2) {
            double angle = getAngle(x1, y1, x2, y2);
            return Direction.get(angle);
        }

        /**
         * Finds the angle between two points in the plane (x1,y1) and (x2, y2)
         * The angle is measured with 0/360 being the X-axis to the right, angles
         * increase counter clockwise.
         *
         * @param x1 the x position of the first point
         * @param y1 the y position of the first point
         * @param x2 the x position of the second point
         * @param y2 the y position of the second point
         * @return the angle between two points
         */
        public double getAngle(float x1, float y1, float x2, float y2) {

            double rad = Math.atan2(y1 - y2, x2 - x1) + Math.PI;
            return (rad * 180 / Math.PI + 180) % 360;
        }



    }
}

自定义卡片 View :

package com.pranapps.testontouch;

import android.content.Context;
import android.support.v7.widget.CardView;
import android.util.AttributeSet;
import android.view.MotionEvent;

/**
 * Created by pranoychowdhury on 5/9/16.
 */
public class CustomCardView extends CardView {
    public CustomCardView(Context context) {
        super(context);
    }

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

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

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {

        //System.out.println("Touched custom from card");
        return false;
    }


}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<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="com.pranapps.testontouch.MainActivity"
    android:id="@+id/layout"
    >



<com.pranapps.testontouch.CustomCardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_gravity="center"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:id="@+id/mycardview"
    card_view:cardUseCompatPadding="true">

    <ListView
        android:layout_width="match_parent"
        android:layout_height="fill_parent"
        android:id="@+id/myListView"
        android:dividerHeight="0.2dp"
        android:overScrollMode="always"
        android:smoothScrollbar="true"
        android:groupIndicator="@null"
        ></ListView>



</com.pranapps.testontouch.CustomCardView>

</RelativeLayout>

关于cardview onTouch监听器冲突/灵敏度中的android listview,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37358015/

相关文章:

android - 在 LinearLayout 中使用 Gridview 和 Button

Android edittext 自动随文本增长并向下推

android-layout - 在 Android 中以编程方式实现切换按钮的 "android:textOff"和 "android:textOn"属性

java - 从 ListView 到 PDF 的数据

android - 获取设备上运行的应用程序的图标

android - 谷歌地图路由 api V2 android

android - 带有 ActionBarSherlock 库的 OnCreateOptionsMenu

java - 改造、实时数据适配器、使响应类包装器通用?

android - Android游戏中的滑动棋子

Android ViewHolder 和类广播异常