android listview dentro cardview conflito de ouvintes onTouch / sensibilidade

Aqui está um projeto de teste que mostra o link do dropbox do problema:https://www.dropbox.com/sh/8s3v9ydcj6jvpl8/AACZ2VRP2N9R1ec7pxrsAn0ga?dl=0

Esta é uma continuação da pergunta que tive aqui, que foi respondida, mas agora estou perguntando sobre a sensibilidade / conflito do onTouch:Android CardView com ListView dentro - onTouchListener no CardView não está funcionando

Eu tenho um cardview com um listview dentro. Também precisarei do item de rolagem e clique na exibição em lista e também quero poder mover a visualização de cartão inteira usando o ontouchlistener. Eu configurei um onTouchListener na visualização do cartão, mas ele não funciona corretamente, pois o rolagem da exibição em lista está em conflito com o movimento da visualização do cartão.

Consegui obter algo semelhante para funcionar perfeitamente no iOS, por isso também deve ser possível no Android.

Código:

Coloque isso em build.gradle:

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

Atividade principal:

    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);

    }
}

O ouvinte do cardview onTouch e o listview detectam o toque agora. No entanto, quando tento mover o cardview, o listview continua tentando rolar. E quando tento rolar na lista, o cartão se move intead.

Eu entendo por que isso está acontecendo. Basicamente, o ouvinte do onTouch parece estar em conflito com o movimento do cardview com a rolagem do listview, mas não sei como descobrir no código se estou tentando rolar ou mover o cardview.

XML para MainActivity:

    <?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>

Código CustomCardView:

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;
    }
}

Por favor, ajude com sugestões para tentar! Obrigado!

Editar: Aqui está um vídeo de como funciona no iOS. Eu posso rolar na lista. Panoramizar para a esquerda ou direita faz o cartão se mover.https://www.dropbox.com/s/5dm52vtjb1xgcl5/iOS.mov?dl=0

A visualização do cartão não será rolada, apenas o conteúdo dentro da visualização do cartão (que é a visualização da lista) será rolado. A visualização do cartão só pode se mover rastreando os dedos. Imagine o tinder onde os cartões podem ser movidos e, dentro do cartão, você pode rolar.

questionAnswers(2)

yourAnswerToTheQuestion