6

Ecco un progetto di test che mostra il legame problema set: https://www.dropbox.com/sh/8s3v9ydcj6jvpl8/AACZ2VRP2N9R1ec7pxrsAn0ga?dl=0listview Android all'interno CardView onTouch conflitto ascoltatore/sensibilità

Questa è una continuazione della domanda che ho avuto qui che è stato risposto, ma ora mi sto chiedendo circa la sensibilità/conflitto di onTouch: Android CardView with ListView inside - onTouchListener on CardView not working

Ho un cardview con un listview all'interno. Avrò bisogno anche della voce di scroll e click nella visualizzazione elenco e voglio essere in grado di spostare l'intera cardview usando anche l'onuchlistener. Ho impostato un onTouchListener sul cardview ma non funziona correttamente in quanto lo scroll di listview è in conflitto con il movimento cardview.

Sono stato in grado di ottenere cose simili per funzionare perfettamente su iOS, quindi dovrebbe essere possibile farlo anche su Android.

Codice:

Mettere questo in build.gradle:

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

MainActivity:

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

    } 
} 

Sia il CardView onTouch ascoltatore e il listview fanno rilevare il tocco ora. Tuttavia, quando provo a spostare il cardview, il listview continua a provare a scorrere. E quando provo a scorrere sulla lista, la carta si muove in avanti.

Capisco perché questo sta accadendo. Fondamentalmente l'ascoltatore onTouch sembra essere in conflitto con il movimento cardview con scroll di lista, ma non sono sicuro di come capire nel codice se sto provando a scorrere o spostare il cardview in giro.

XML per MainActivity:

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

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

Si prega di aiutare con suggerimenti da provare! Grazie!

Modifica: Ecco un video di come funziona su iOS. Posso scorrere sulla listview. La panoramica a sinistra oa destra fa muovere la carta. https://www.dropbox.com/s/5dm52vtjb1xgcl5/iOS.mov?dl=0

Il cardview non scorrerà, solo il contenuto all'interno del cardview (che è il listview) scorrerà. Il cardview può muoversi solo tenendo traccia delle dita. Immagina che le carte possano essere giocate e all'interno della carta puoi scorrere.

+0

Date un'occhiata a questo http://stackoverflow.com/questions/30966412/how-to-vary- tra-child-e-parent-view-group-touch-events/30966413 # 30966413, potrebbe essere utile, se avrò tempo scriverò e risponderò per te –

+0

@Yvette grazie per il tuo commento! Ho letto quella soluzione. Attualmente ho già implementato onInterceptTouchEvent per la personalcardview e restituisco solo true. Non capisco come rendere il mio codice abbastanza intelligente da capire se l'utente sta cercando di scorrere su listview o scorrere la carta. Un modo sarebbe di avere un ritardo all'inizio durante il quale utilizzo i punti di contatto per capire quale è. Ma il ritardo sarebbe inaccettabile, inoltre non sono sicuro di come andare in giro a implementarlo. Se hai una possibilità, per favore aiutaci! Grazie! –

+0

@Yvette hai altre idee? –

risposta

2

sono stato in grado di risolvere questo io stesso dopo 2 settimane di sperimentazione.

Ho rimosso onInterceptTouchEvent e ontouch dal cardview. Invece, crea un OnTouchListener personalizzato e collegalo alla listview stessa. Quindi, nel custom OnTouchListener, prova a capire l'angolo con cui il touch sta andando. se l'angolo all'interno di un intervallo specifico, quindi su o giù scorrere. altri saggi left/right swipe.L'angolo che sto ancora provando a calibrare per capire qual è il migliore per l'usabilità saggia, ma questo sembra funzionare decentemente bene.

ho avuto un po 'di aiuto da questo link per angoli di calcolo: How to detect swipe direction between left/right and up/down

Soluzione:

MainActivity:

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



    } 
} 

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

     //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> 
+1

contento che tu abbia risolto il problema –

+0

grazie signore! Sono contento anch'io –

0

CardView è sempre messa a fuoco in modo da cercare di aggiungere android:descendantFocusability="blocksDescendants" nella vista carta come

<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" 
android:descendantFocusability="blocksDescendants"> //here your listview </com.pranapps.testontouch.CustomCardView> 
+0

ancora lo stesso problema. Il cardview si muove e tenta anche di scorrere la lista. lista di scorrimento non funziona correttamente, i gesti si interrompono a vicenda quindi a volte l'elenco cerca di scorrere, a volte la carta tenta di spostarsi –