2016-02-25 3 views
0

J'essaie de déplacer un objet entre max_height et min_height valeur, j'ai trouvé un morceau de code et j'ai essayé de l'adapter, mais l'objet (CardView) se déplace de toute sa hauteur de l'écran, et quand j'essaie de déplacer l'objet réapparaît dans un autre endroit avant de bouger, je ne sais pas comment l'adapter à mes besoins, à des idées?Déplacer l'objet vers le haut/bas avec le geste de balayage

public interface OnLayoutCloseListener { 
    void OnLayoutClosed(); 
} 

enum Direction { 
    UP_DOWN, 
    LEFT_RIGHT, 
    NONE 
} 
private Direction direction = Direction.NONE; 
private int previousFingerPositionY; 
private int previousFingerPositionX; 
private int baseLayoutPosition; 
private boolean isScrollingUp; 
private boolean isLocked = false; 
private OnLayoutCloseListener listener; 

@Override 
public boolean onInterceptTouchEvent(MotionEvent ev) { 

    if (isLocked) { 
     return false; 
    } else { 
     final int y = (int) ev.getRawY(); 
     final int x = (int) ev.getRawX(); 


     if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) { 

      previousFingerPositionX = x; 
      previousFingerPositionY = y; 

     } else if (ev.getActionMasked() == MotionEvent.ACTION_MOVE) { 


      int diffY = y - previousFingerPositionY; 
      int diffX = x - previousFingerPositionX; 

      if (Math.abs(diffX) + 50 < Math.abs(diffY)) { 
       return true; 
      } 

     } 

     return false; 
    } 

} 

@Override 
public boolean onTouchEvent(MotionEvent ev) { 

    if (!isLocked) { 

     final int y = (int) ev.getRawY(); 
     final int x = (int) ev.getRawX(); 

     if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) { 

      previousFingerPositionX = x; 
      previousFingerPositionY = y; 
      baseLayoutPosition = (int) this.getY(); 

     } else if (ev.getActionMasked() == MotionEvent.ACTION_MOVE) { 


      int diffY = y - previousFingerPositionY; 
      int diffX = x - previousFingerPositionX; 

      if (direction == Direction.NONE) { 
       if (Math.abs(diffX) > Math.abs(diffY)) { 
        direction = Direction.LEFT_RIGHT; 
       } else if (Math.abs(diffX) < Math.abs(diffY)) { 
        direction = Direction.UP_DOWN; 
       } else { 
        direction = Direction.NONE; 
       } 
      } 

      if (direction == Direction.UP_DOWN) { 
       isScrollingUp = diffY <= 0; 

       this.setY(baseLayoutPosition + diffY); 
       requestLayout(); 
       return true; 
      } 

     } else if (ev.getActionMasked() == MotionEvent.ACTION_UP) { 

      if (direction == Direction.UP_DOWN) { 

       if (isScrollingUp) { 

        //Calculates height according to my needs 
        int max_height = height - (card.getHeight() + toolbar.getHeight()); 

        if (Math.abs(this.getY()) > max_height) { 

         if (listener != null) { 
          listener.OnLayoutClosed(); 
         } 

        } 

       } else { 

        //Calculates height according to my needs 
        int min_height = height - ((int)(toolbar.getHeight() * 1.7)); 
        if (Math.abs(this.getY()) > min_height) { 
         if (listener != null) { 
          listener.OnLayoutClosed(); 
         } 

        } 

       } 

       ObjectAnimator positionAnimator = ObjectAnimator.ofFloat(card, "y", this.getY(), 0); 
       positionAnimator.setDuration(0); 
       positionAnimator.start(); 

       direction = Direction.NONE; 
       return true; 
      } 

      direction = Direction.NONE; 
     } 

     return true; 

    } 

    return false; 
} 

public void setOnLayoutCloseListener(OnLayoutCloseListener closeListener) { 
    this.listener = closeListener; 
} 

public void lock() { 
    isLocked = true; 
} 

public void unLock() { 
    isLocked = false; 
} 

SOLUTION MISE À JOUR:

Réinitialiser LayoutParam à une instance de la carte:

card.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); 

que d'utiliser ce code pour une vue de défilement entre min_height et max_height

private int previousFingerPositionY; 
private int previousFingerPositionX; 
int min_height = 500; 
int max_height = 100; 
int pressedy; 
int viewMariginY; 

private boolean isLocked = false; 
@Override 
public boolean onInterceptTouchEvent(MotionEvent ev) { 
    if (isLocked) { 
     return false; 
    } else { 
     final int y = (int) ev.getRawY(); 
     final int x = (int) ev.getRawX(); 
     if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) { 
      previousFingerPositionX = x; 
      previousFingerPositionY = y; 
     } else if (ev.getActionMasked() == MotionEvent.ACTION_MOVE) { 
      int diffY = y - previousFingerPositionY; 
      int diffX = x - previousFingerPositionX; 
      if (Math.abs(diffX) + 25 < Math.abs(diffY)) { 
       return true; 
      } 
     } 
     return false; 
    } 
} 

@Override 
public boolean onTouchEvent(MotionEvent event) { 

    int currenty=(int) event.getRawY(); 
    FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) card.getLayoutParams(); 
    switch(event.getAction()) 
    { 

     case MotionEvent.ACTION_DOWN : 
      pressedy=currenty; 
      viewMariginY=layoutParams.topMargin; 
      break; 


     case MotionEvent.ACTION_MOVE : 
      int diffy=currenty-pressedy; 
      int marginy=viewMariginY+diffy; 
      layoutParams.topMargin=marginy; 
      if(marginy >= max_height && marginy <= min_height) 
      { 
       ObjectAnimator positionAnimator = ObjectAnimator.ofFloat(card, "y", this.getY(), marginy); 
       positionAnimator.setDuration(0); 
       positionAnimator.start(); 
      } 
      break; 

     case MotionEvent.ACTION_UP : 
      int diffy2=currenty-pressedy; 
      int marginy2=viewMariginY+diffy2; 
      layoutParams.topMargin=marginy2; 
      if(marginy2 >= max_height && marginy2 <= min_height) 
      { 
       ObjectAnimator positionAnimator1 = ObjectAnimator.ofFloat(card, "y", this.getY(), marginy2); 
       positionAnimator1.setDuration(0); 
       positionAnimator1.start(); 
      } 
      break; 
    } 

    return true; 
} 

Répondre

1
int pressedx,pressedy; 
    int viewMariginX,viewMariginY; 

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

    int currentx=(int) event.getRawX(); 
    int currenty=(int) event.getRawY(); 


//get Layout Param of your cardView 

    FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) v.getLayoutParams(); 

    switch(event.getAction()) 
    { 

    case MotionEvent.ACTION_DOWN : 

     pressedx=currentx; 
     pressedy=currenty; 

     viewMariginX=layoutParams.leftMargin; 
     viewMariginY=layoutParams.topMargin; 
     break; 


    case MotionEvent.ACTION_MOVE : 

     int diffx=currentx-pressedx; 
     int diffy=currenty-pressedy; 

     int marginx=viewMariginX+diffx; 
     int marginy=viewMariginY+diffy; 


     layoutParams.leftMargin=marginx; 
     layoutParams.topMargin=marginy;  
     v.setLayoutParams(layoutParams);   
     break; 

    case MotionEvent.ACTION_UP : 

     int diffx2=currentx-pressedx; 
     int diffy2=currenty-pressedy; 

     int marginx2=viewMariginX+diffx2; 
     int marginy2=viewMariginY+diffy2; 


     layoutParams.leftMargin=marginx2; 
     layoutParams.topMargin=marginy2;    
     v.setLayoutParams(layoutParams);  
     break; 
    } 

    return true; 
} 

Votre référence est similaire à ce que je fait il y a quelques jours.

Il prend la différence de deux positions et les ajoute à la marge de vue actuelle de gauche et de haut.

Vous pouvez conserver la position de la vue en sauvegardant ces valeurs de marge.

NOTE: Vous devez prendre soin de votre MAX et MIN Bounds

espérons qu'il vous aidera ...

MISE À JOUR: 1) Fixer onTouchListners sur vous autant que cardviews vous voulez

cardview.setOnTouchListener (this); cardview1.setOnTouchListener (this);

OnTouch (Affichage v, événement MotionEvent) Appelé lorsqu'un événement tactile est envoyé à une vue. Cela permet aux auditeurs d'avoir une chance de répondre avant la vue cible.

Spécifié par: onTouch (...) dans OnTouchListener Paramètres: v: L'affichage de l'événement tactile a été envoyé à. event: Objet MotionEvent contenant des informations complètes sur l'événement. par docs.

changer votre OnTouch dans la Vignettes v

De votre question

FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) v.getLayoutParams();

ObjectAnimator positionAnimator = ObjectAnimator.ofFloat (v, «y», this.getY(), marginy); positionAnimator.setDuration (0); positionAnimator.start();

changer d'autres références dans la même méthode.

2) Le problème de réglage des limites est simple Vérification de la condition juste avant de changer de position.

et désolé pour une mauvaise explication.

+0

Ce param ... –

+0

Il va modifier les marges de votre carte Voir si vous ne voulez pas juste remplacer le code param avec votre code de traduction puisque vous avez la différence relative maintenant .. –

+0

J'ai mis à jour la réponse –

0

Cette animation:

ObjectAnimator positionAnimator = ObjectAnimator.ofFloat(card, "y", this.getY(), 0); 

déplace la vue sur l'axe vertical de la position this.getY() y à 0 (en haut de l'écran). Je vois que vous définissez des limites max_height et min_height, mais vous ne les utilisez pas du tout.

Je ne suis pas sûr de ce que vous êtes les exigences sont, mais vous pouvez faire quelque chose comme ceci:

ObjectAnimator positionAnimator = ObjectAnimator.ofFloat(card, "y", this.getY(), (Math.abs(this.getY() - min_height) < Math.abs(this.getY() - max_height))?min_height:max_height); 

Ce que cela va faire est de déplacer l'objet à min_height ou max_height basé sur lequel est le plus proche .

La vue semble être animé aussi par cela appelle this.setY(baseLayoutPosition + diffY); requestLayout();, vous devrez vous assurer que baseLayoutPosition + diffY est dans les limites, quelque chose comme:

int amount = baseLayoutPosition + diffY; 
this.setY(Math.min(max_height, Math.max(min_height, amount))); 
+0

oui mais il se déplacer toute la hauteur de l'écran ... Je voudrais entre la hauteur min et max, et commencer à partir de min –

+0

@MicheleLacorte Dans ce cas, essayez: 'ObjectAnimator.ofFloat (carte," y ", min_height, max_height); ' – Titus

+0

ça ne marche pas .. –