2016-02-12 46 views
12

Un semplice codice qui sotto per mostrare lo Snackbar.Ignora snack bar Sullo scorrimento a sinistra

public void onClick(View view) { 
     Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_INDEFINITE) 
       .setAction("Action", null).show(); 
} 

Questo codice mostra correttamente la Snackbar, quando si verifica onClick evento.

Inoltre, questo snack bar può essere rimosso con un semplice gesto.

Tuttavia, per impostazione predefinita, solo Right-swipe sta chiudendo lo Snackbar. E non riesco a respingerlo con il tasto sinistro del mouse.

Come liquidare lo snackbar su left-swipe?

+0

hai trovato una soluzione a questo? –

+0

@JakubHolovsky No. Come puoi vedere, non c'è nessuna risposta pubblicata sotto questo post. E ha quasi 6 mesi ... quindi suppongo che questo sia un limite della piattaforma in questo momento. – AADProgramming

+1

** Snackbar ** ha bisogno di un ** CoordinatorLayout ** come suo layout di root o di alcuni dove su di esso, per eseguire le sue varie operazioni come ** scorri per chiudere **. Puoi trovare una domanda simile [qui] (http://stackoverflow.com/questions/38823767/snackbar-is-not-dismissing-on-swipe) – Bee

risposta

4

Ciò respingere snackBar su swipes sinistra (ma senza che l'animazione su scorri verso sinistra)

  • uso getView() e prendere il layout di snackBar
  • uso setOnTouchListener
  • rilevare il movimento ed eseguire la vostra azione

e il suo Fatto!

public class HomeActivity extends AppCompatActivity { 

      private float x1,x2; 
      static final int MIN_DISTANCE = 150; 

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

       RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.rel); 

       final Snackbar snackbar = Snackbar.make(relativeLayout, "Helloo", Snackbar.LENGTH_INDEFINITE); 
       Snackbar.SnackbarLayout layout = (Snackbar.SnackbarLayout) snackbar.getView(); 
       layout.setOnTouchListener(new View.OnTouchListener() { 
        @Override 
        public boolean onTouch(View v, MotionEvent event) { 
         switch(event.getAction()) 
         { 
          case MotionEvent.ACTION_DOWN: 
            x1 = event.getX(); 
            break; 
          case MotionEvent.ACTION_UP: 
            x2 = event.getX(); 
            float deltaX = x2 - x1; 
           if (Math.abs(deltaX) > MIN_DISTANCE) 
            {// Left to Right swipe action 
             if (x2 > x1) 
             { 
              Toast.makeText(HomeActivity.this, "Left to Right swipe ", Toast.LENGTH_SHORT).show(); 
             } 
             // Right to left swipe action 
             else 
             { 
              Toast.makeText(HomeActivity.this, "Right to Left swipe ", Toast.LENGTH_SHORT).show(); 
              snackbar.dismiss(); 
             } 
            } 
            else 
            { 
             Toast.makeText(HomeActivity.this, "Tap or Else", Toast.LENGTH_SHORT).show(); 
            } 
            break; 
          } 

         return false; 
        } 
       }); 
       snackbar.show(); 
      } 
     } 
1

speranza che questo vi aiuterà:

OnSwipeTouchListener.java:

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

public class OnSwipeTouchListener implements OnTouchListener { 

    private final GestureDetector gestureDetector; 

    public OnSwipeTouchListener (Context ctx){ 
     gestureDetector = new GestureDetector(ctx, new GestureListener()); 
    } 

    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
     return gestureDetector.onTouchEvent(event); 
    } 

    private final class GestureListener extends SimpleOnGestureListener { 

     private static final int SWIPE_THRESHOLD = 100; 
     private static final int SWIPE_VELOCITY_THRESHOLD = 100; 

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

     @Override 
     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { 
      boolean result = false; 
      try { 
       float diffY = e2.getY() - e1.getY(); 
       float diffX = e2.getX() - e1.getX(); 
       if (Math.abs(diffX) > Math.abs(diffY)) { 
        if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) { 
         if (diffX > 0) { 
          onSwipeRight(); 
         } else { 
          onSwipeLeft(); 
         } 
        } 
        result = true; 
       } 
       else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) { 
         if (diffY > 0) { 
          onSwipeBottom(); 
         } else { 
          onSwipeTop(); 
         } 
        } 
        result = true; 

      } catch (Exception exception) { 
       exception.printStackTrace(); 
      } 
      return result; 
     } 
    } 

    public void onSwipeRight() { 
    } 

    public void onSwipeLeft() { 
    } 

    public void onSwipeTop() { 
    } 

    public void onSwipeBottom() { 
    } 
} 

come utilizzare: On MainActivity

public class MainActivity extends AppCompatActivity { 
    CoordinatorLayout coordinatorLayout; 

    private Snackbar snackbar; 

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

     coordinatorLayout = (CoordinatorLayout)findViewById(R.id.coordinatorLayout); 

     snackbar = Snackbar 
       .make(coordinatorLayout, "Replace with your own action", Snackbar.LENGTH_INDEFINITE) 
       .setAction("RETRY", null); 

     snackbar.setActionTextColor(Color.RED); 

     View sbView = snackbar.getView(); 
     TextView textView = (TextView) sbView.findViewById(android.support.design.R.id.snackbar_text); 
     textView.setTextColor(Color.YELLOW); 
     snackbar.show(); 

     textView.setOnTouchListener(new OnSwipeTouchListener(MainActivity.this) 
     { 
      public void onSwipeTop() { 

      } 
      public void onSwipeRight() { 

      } 
      public void onSwipeLeft() { 
       snackbar.dismiss(); 
      } 
      public void onSwipeBottom() { 

      } 
     }); 

    } 
} 
+0

fammi provare questo codice – AADProgramming

1

nei commenti qualcuno ha suggerito l'utilizzo di CoordinatorLayout.Behavior, questo è l'approccio giusto. Gestire l'evento touch da solo, è quasi una buona idea, ma non l'approccio giusto, perché "interromperà" l'implementazione interna di Snackbar e del suo Manager.

È necessario sostituire il valore predefinito SwipeToDismissBehavior dello Snackbar subito dopo il metodo calll show().

 Snackbar snackbar = Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_INDEFINITE) 
      .setAction("Action", null).show(); 
    View snackBarView = snackbar.getView(); 
    final ViewGroup.LayoutParams lp = snackBarView.getLayoutParams(); 
    if (lp instanceof CoordinatorLayout.LayoutParams) { 
     final CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) lp; 
     final SwipeDismissBehavior<Snackbar.SnackbarLayout> behavior = new SwipeDismissBehavior<Snackbar.SnackbarLayout>(); 
     behavior.setStartAlphaSwipeDistance(0.1f); 
     behavior.setEndAlphaSwipeDistance(0.6f); 
     behavior.setSwipeDirection(SwipeDismissBehavior.SWIPE_DIRECTION_END_TO_START); 
     behavior.setListener(new SwipeDismissBehavior.OnDismissListener() { 
      @Override 
      public void onDismiss(View view) { 
       snackbar.dismiss(); 
      } 

      @Override 
      public void onDragStateChanged(int state) { 
       switch (state) { 
        case SwipeDismissBehavior.STATE_DRAGGING: 
        case SwipeDismissBehavior.STATE_SETTLING: 
         snackbar.show(); 
         break; 
        case SwipeDismissBehavior.STATE_IDLE: 
         break; 
       } 
      } 
     }); 
     layoutParams.setBehavior(behavior); 
    } 

o più corto approccio:

View snackBarView = snackbar.getView(); 
    final ViewGroup.LayoutParams lp = snackBarView.getLayoutParams(); 
    if (lp instanceof CoordinatorLayout.LayoutParams) { 
     final CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) lp; 
     CoordinatorLayout.Behavior behavior = layoutParams.getBehavior(); 
     if(behavior instanceof SwipeDismissBehavior){ 
      ((SwipeDismissBehavior) behavior).setSwipeDirection(SwipeDismissBehavior.SWIPE_DIRECTION_END_TO_START); // or SwipeDismissBehavior.SWIPE_DIRECTION_ANY 
     } 
     layoutParams.setBehavior(behavior); 
    } 
+0

Il tuo approccio più breve sembra di gran lunga l'opzione migliore di tutte le risposte presentate. – Benjamin

+1

su avvertenza per l'approccio più breve. Lo snippet di codice deve essere eseguito nel callback 'onShown (Snackbar)'. Se eseguito prima di allora, 'getBehavior()' restituirà null. – Benjamin

+0

funziona. approccio migliore e pulito insieme al commento in 'onShown' di @Benjamin – vida