2016-02-12 80 views
12

下面的簡單代碼用於顯示Snackbar。關閉Snackbar左側滑動

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

此代碼正確顯示Snackbar,當onClick事件發生時。

另外,這個小吃店可以通過輕掃手勢解僱。

但默認情況下,只有右擊正在解散Snackbar。我無法用左手輕掃來解僱它。

如何關閉小吃店左側滑動

+0

你找到一個解決的辦法? –

+0

@JakubHolovsky不,你可以看到,這篇文章下面沒有答覆。而且已經差不多6個月大了......所以我現在假設這是一個平臺限制。 – AADProgramming

+1

** Snackbar **需要一個** CoordinatorLayout **作爲它的根佈局或一些位於其上的位置,以執行其各種操作,如**輕掃以解除**。你可以找到一個類似的問題[這裏](http://stackoverflow.com/questions/38823767/snackbar-is-not-dismissing-on-swipe) – Bee

回答

4

這將解僱snackBar上左刷卡(但沒有對動畫向左滑動)

  • 使用getView()並採取snackBar佈局
  • 使用setOnTouchListener
  • 檢測移動並執行你的行動

及其完成!

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

希望這將有助於:

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

如何使用:在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

讓我試試這個代碼 – AADProgramming

1

在評論中有人建議使用CoordinatorLayout.Behavior,這是正確的做法。自己處理觸摸事件幾乎是個好主意,但沒有正確的方法,因爲它會「打破」Snackbar及其管理器的內部實現。

在調用show()方法之後,您需要替換Snackbar的默認SwipeToDismissBehavior

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

或更短的做法:

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

你的簡短方法似乎是所有答案的最佳選擇。 – Benjamin

+1

關於更短途徑的警告。代碼片段需要在'onShown(Snackbar)'回調中運行。如果在那之前運行,'getBehavior()'將返回null。 – Benjamin

+0

工程。 @Benjamin在'onShown'中發表評論時最好和乾淨的方法 – vida