向左滑动关闭快捷栏

问题描述 投票:0回答:5

下面的简单代码用于显示 Snackbar。

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

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

此外,可以通过滑动手势关闭此小吃栏。

但默认情况下,只有右滑动会关闭 Snackbar。而且我无法通过向左滑动来关闭它。

如何在向左滑动时关闭小吃栏?

android onclick android-snackbar
5个回答
10
投票

另一种简单且干净的方法可能如下:

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
回调。


5
投票

希望这会有所帮助:

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

            }
        });

    }
}

3
投票

在评论中有人建议使用

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

2
投票

这将在向左滑动时消除

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

0
投票
Snackbar snackbar = Snackbar.make(view, message, Snackbar.LENGTH_LONG);
snackbar.getBehavior().setSwipeDirection(SwipeDismissBehavior.SWIPE_DIRECTION_ANY);
snackbar.show();
© www.soinside.com 2019 - 2024. All rights reserved.