2016-02-12 85 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