代码之家  ›  专栏  ›  技术社区  ›  AADProgramming

向左滑动时关闭小吃店

  •  16
  • AADProgramming  · 技术社区  · 9 年前

    下面是显示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 回复  |  直到 9 年前
        1
  •  7
  •   epool    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 回调。

        2
  •  4
  •   Aldi Renaldi Gunawan    8 年前

    希望这将有助于:

    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 Main Activity

     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
  •  3
  •   Nikola Despotoski    8 年前

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

    您需要替换默认值 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);
        }
    
        4
  •  2
  •   Charuක    8 年前

    这将解除 snackBar 向左滑动(但没有向左滑动的动画)

    • 使用 getView() 并采取 快照栏 布局
    • 使用 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();
                }
            }