Уволить закусочную по левому свайпу
Простой код ниже для показа закусочной.
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_INDEFINITE)
.setAction("Action", null).show();
}
Этот код правильно показывает закусочную, когда происходит событие onClick
.
Кроме того, эта закусочная может быть отклонена жестом салфетки.
Но по умолчанию толькоправый свайп отключает закусочную. И я не могу отмахнуться от него с помощью левого свайпа.
Как отключить snackbar на левый свайп ?
3 ответа:
Это отклонит
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(); } }
Надеюсь, это поможет :
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() { } }
Как использовать: 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() { } }); } }
В комментариях кто-то предложил использовать
CoordinatorLayout.Behavior
, это правильный подход. Обработка события касания самостоятельно, это почти хорошая идея, но нет правильного подхода, потому что это "сломает" внутреннюю реализацию Snackbar и его менеджера.Вам нужно заменить default
SwipeToDismissBehavior
изSnackbar
сразу после вызова метода 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); }
Или более короткий подход:
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); }