定制的Andr​​oid视图与4方向轻扫手势视图、手势、方向、Andr

2023-09-05 10:10:58 作者:愿风裁尘

我工作的一个Android应用程序,显示了一系列的卡。每张卡花费几乎整个屏幕。我希望用户能够通过刷卡左,右和该ViewPager的工作很好,以查看previous和下一个卡。

I am working on an Android App which shows a series of cards. Each card almost takes the whole screen. I want the user to be able to view the previous and next cards by swiping left and right and for that ViewPager is working nicely.

不过,我也希望用户能够刷卡上下卡喜欢/不喜欢一个吧。挥击向上/向下手势应该根据用户的手势/向下的卡向上移动。后一个刷卡上/下,应当从卡的列表中删除。

However I also want the user to be able to swipe up and down a card to like/dislike a it. The swipe up/down gesture should move up/down the card according to the user's hand gesture. After a card is swiped up/down, it should be removed from the list of cards.

我在网上搜索了一个解决方案或服装景色。不过,最让我找到了解决方案,为2方位的刷卡(或左/右或上/下)。有没有一个很好的解决方案或库的4方向滑动查看?

I searched online for a solution or a costume view. But most of the solutions I found are for 2-directional swipes (either left/right or up/down). Is there a nice solution or a library for a 4-directional Swipe View?

推荐答案

在一些在线调查,我想出了下面的实现,它工作得很好。所述CardView类扩展片段可以在一个类中使用。

After some online research, I came up with the following implementation which works nicely. The CardView class extends Fragment which can be used in a class.

    public class CardView extends Fragment {
        private static float CARDS_SWIPE_LENGTH = 250;
        private float originalX = 0;
        private float originalY = 0;    
        private float startMoveX = 0;
        private float startMoveY = 0;

        public CardView() {
            super();
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.card_template, container, false);

            rootView.setOnTouchListener(new View.OnTouchListener() {
                public boolean onTouch(View view, MotionEvent event) {
                        final float X = event.getRawX();
                        final float Y =  event.getRawY();
                        float deltaX = X - startMoveX;
                        float deltaY = Y - startMoveY;
                        switch (event.getAction() & MotionEvent.ACTION_MASK) {
                            case MotionEvent.ACTION_DOWN:
                                startMoveX = X;
                                startMoveY = Y;
                                break;
                            case MotionEvent.ACTION_UP:
                                childView.getBackground().setColorFilter(R.color.color_card_background, PorterDuff.Mode.DST);
                                if ( Math.abs(deltaY) < CARDS_SWIPE_LENGTH ) {
                                    rootView.setX(originalX);
                                    rootView.setY(originalY);
                                } else if ( deltaY > 0 ) { 
                                    onCardSwipeDown();
                                } else {
                                    onCardSwipeUp();
                                }
                                break;
                            case MotionEvent.ACTION_POINTER_DOWN:
                                break;
                            case MotionEvent.ACTION_POINTER_UP:
                                break;
                            case MotionEvent.ACTION_MOVE:
                                int newColor = 0;
                                if ( deltaY < 0 ) {
                                    int rb = (int)(255+deltaY/10);
                                    newColor = Color.argb(170, rb, 255, rb);
                                } else {
                                    int gb = (int)(255-deltaY/10);
                                    newColor = Color.argb(170, 255, gb, gb);                                
                                }
                                rootView.getBackground().setColorFilter(newColor, PorterDuff.Mode.DARKEN);
                                rootView.setTranslationY(deltaY);
                                break;
                        }
                        rootView.invalidate();
                    return true;
                }
            });
            return rootView;
        }

        protected void onCardSwipeUp() {
            Log.i(AppUtil.APP, "Swiped Up");
        }

        protected void onCardSwipeDown() {
            Log.i(AppUtil.APP, "Swiped Down");
        }

    }
}