在左侧滑动时关闭Snackbar

时间:2016-02-12 06:25:14

标签: android onclick android-snackbar

以下简单代码显示Snackbar。

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

此代码在onClick事件发生时正确显示Snackbar。

此外,这个小吃店可以通过轻扫手势解散。

但默认情况下,只有右键滑动才会关闭Snackbar。我无法用左键轻扫它。

如何解除左键滑动上的零食栏?

4 个答案:

答案 0 :(得分:5)

另一种更简单,更简洁的方法可能是:

val behavior = BaseTransientBottomBar.Behavior().apply {
    setSwipeDirection(SwipeDismissBehavior.SWIPE_DIRECTION_ANY)
}
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_INDEFINITE)
    .setBehavior(behavior)
    .show()

您无需检查和转换布局参数,也无需使用onShown回调。

答案 1 :(得分: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();
            }
        }

答案 2 :(得分:2)

希望这会有所帮助:

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

            }
        });

    }
}

答案 3 :(得分:1)

在评论中有人建议使用CoordinatorLayout.Behavior,这是正确的方法。自己处理触摸事件几乎是个好主意,但没有正确的方法,因为它会“破坏”Snackbar及其管理器的内部实现。

您需要在调用show()方法后替换SwipeToDismissBehavior的默认Snackbar

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