具有4向滑动手势的自定义Android视图

具有4向滑动手势的自定义Android视图,android,android-viewpager,swipe,Android,Android Viewpager,Swipe,我正在开发一个Android应用程序,它显示一系列卡片。每张卡片几乎占据了整个屏幕。我希望用户能够通过左右滑动查看上一张和下一张卡片,并且ViewPager工作得很好 然而,我也希望用户能够上下滑动一张卡片来喜欢/不喜欢它。向上/向下滑动手势应根据用户的手势向上/向下移动卡。向上/向下刷卡后,应将其从卡列表中删除 我在网上搜索解决方案或服装视图。但我发现的大多数解决方案都是双向滑动(左/右或上/下)。是否有一个很好的解决方案或库用于4向滑动视图?您可以使用ViewPager在卡之间切换。你可以@

我正在开发一个Android应用程序,它显示一系列卡片。每张卡片几乎占据了整个屏幕。我希望用户能够通过左右滑动查看上一张和下一张卡片,并且ViewPager工作得很好

然而,我也希望用户能够上下滑动一张卡片来喜欢/不喜欢它。向上/向下滑动手势应根据用户的手势向上/向下移动卡。向上/向下刷卡后,应将其从卡列表中删除


我在网上搜索解决方案或服装视图。但我发现的大多数解决方案都是双向滑动(左/右或上/下)。是否有一个很好的解决方案或库用于4向滑动视图?

您可以使用ViewPager在卡之间切换。你可以@Override the motionEvents of Up and Down来做你想做的任何事情。您可以将它们存储在ArrayAdapter中,以便在它们之间切换。当用户向下或向上滑动时,从适配器中取出卡,并使用viewPager.setCurrentItem(viewPager.getCurrentItem()+1)转到下一张卡


您可以使用ViewPager在卡之间切换。你可以@Override the motionEvents of Up and Down来做你想做的任何事情。您可以将它们存储在ArrayAdapter中,以便在它们之间切换。当用户向下或向上滑动时,从适配器中取出卡,并使用viewPager.setCurrentItem(viewPager.getCurrentItem()+1)转到下一张卡


在进行了一些在线研究之后,我提出了以下实施方案,效果很好。CardView类扩展了可在类中使用的片段

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

    }
}
公共类CardView扩展片段{
私人静态浮动卡刷卡长度=250;
私有浮动原始x=0;
私有浮动初始值=0;
专用浮点startMoveX=0;
专用浮点startMoveY=0;
公共CardView(){
超级();
}
@凌驾
CreateView上的公共视图(布局、充气机、视图组容器、捆绑包保存状态){
视图根视图=充气机。充气(R.layout.card_模板,容器,假);
setOnTouchListener(新视图.OnTouchListener(){
公共布尔onTouch(视图、运动事件){
最终浮点X=event.getRawX();
最终浮点Y=event.getRawY();
浮动deltaX=X-开始移动;
浮动三角洲=Y-开始移动;
开关(event.getAction()&MotionEvent.ACTION\u掩码){
case MotionEvent.ACTION\u DOWN:
startMoveX=X;
startMoveY=Y;
打破
case MotionEvent.ACTION\u UP:
childView.getBackground().setColorFilter(R.color.color_card_background,PorterDuff.Mode.DST);
if(数学abs(deltaY)0){
onCardSwipeDown();
}否则{
onCardSwipeUp();
}
打破
case MotionEvent.ACTION\u指针\u向下:
打破
case MotionEvent.ACTION\u指针\u向上:
打破
case MotionEvent.ACTION\u移动:
int newColor=0;
如果(三角洲<0){
int rb=(int)(255+deltaY/10);
newColor=Color.argb(170,rb,255,rb);
}否则{
int gb=(int)(255 deltaY/10);
newColor=Color.argb(170255,gb,gb);
}
rootView.getBackground().setColorFilter(newColor,PorterDuff.Mode.DARKEN);
rootView.setTranslationY(deltaY);
打破
}
rootView.invalidate();
返回true;
}
});
返回rootView;
}
受保护的void onCardSwipeUp(){
Log.i(AppUtil.APP,“刷卡”);
}
受保护的void onCardSwipeDown(){
Log.i(AppUtil.APP,“刷下”);
}
}
}

在进行了一些在线研究之后,我提出了下面的实现,它运行得很好。CardView类扩展了可在类中使用的片段

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

    }
}
公共类CardView扩展片段{
私人静态浮动卡刷卡长度=250;
私有浮动原始x=0;
私有浮动初始值=0;
专用浮点startMoveX=0;
专用浮点startMoveY=0;
公共CardView(){
超级();
}
@凌驾
CreateView上的公共视图(布局、充气机、视图组容器、捆绑包保存状态){
视图根视图=充气机。充气(R.layout.card_模板,容器,假);
setOnTouchListener(新视图.OnTouchListener(){
公共布尔onTouch(视图、运动事件){
最终浮点X=event.getRawX();
最终浮点Y=event.getRawY();
浮动deltaX=X-开始移动;
浮点数deltaY=Y-startMov