使用滑动手势向上/向下移动对象

时间:2016-02-25 16:50:24

标签: java android android-layout android-gesture

我试图在max_heightmin_height值之间移动一个对象,我发现了一段代码,我试图调整它,但是对象({{ 1}})在屏幕的整个高度移动,当我试图移动对象在移动之前重新出现在另一个位置时,我不知道如何使其适应我的需要,任何想法?

CardView

更新解决方案:

在任何卡片实例中重置public interface OnLayoutCloseListener { void OnLayoutClosed(); } enum Direction { UP_DOWN, LEFT_RIGHT, NONE } private Direction direction = Direction.NONE; private int previousFingerPositionY; private int previousFingerPositionX; private int baseLayoutPosition; private boolean isScrollingUp; private boolean isLocked = false; private OnLayoutCloseListener listener; @Override public boolean onInterceptTouchEvent(MotionEvent ev) { if (isLocked) { return false; } else { final int y = (int) ev.getRawY(); final int x = (int) ev.getRawX(); if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) { previousFingerPositionX = x; previousFingerPositionY = y; } else if (ev.getActionMasked() == MotionEvent.ACTION_MOVE) { int diffY = y - previousFingerPositionY; int diffX = x - previousFingerPositionX; if (Math.abs(diffX) + 50 < Math.abs(diffY)) { return true; } } return false; } } @Override public boolean onTouchEvent(MotionEvent ev) { if (!isLocked) { final int y = (int) ev.getRawY(); final int x = (int) ev.getRawX(); if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) { previousFingerPositionX = x; previousFingerPositionY = y; baseLayoutPosition = (int) this.getY(); } else if (ev.getActionMasked() == MotionEvent.ACTION_MOVE) { int diffY = y - previousFingerPositionY; int diffX = x - previousFingerPositionX; if (direction == Direction.NONE) { if (Math.abs(diffX) > Math.abs(diffY)) { direction = Direction.LEFT_RIGHT; } else if (Math.abs(diffX) < Math.abs(diffY)) { direction = Direction.UP_DOWN; } else { direction = Direction.NONE; } } if (direction == Direction.UP_DOWN) { isScrollingUp = diffY <= 0; this.setY(baseLayoutPosition + diffY); requestLayout(); return true; } } else if (ev.getActionMasked() == MotionEvent.ACTION_UP) { if (direction == Direction.UP_DOWN) { if (isScrollingUp) { //Calculates height according to my needs int max_height = height - (card.getHeight() + toolbar.getHeight()); if (Math.abs(this.getY()) > max_height) { if (listener != null) { listener.OnLayoutClosed(); } } } else { //Calculates height according to my needs int min_height = height - ((int)(toolbar.getHeight() * 1.7)); if (Math.abs(this.getY()) > min_height) { if (listener != null) { listener.OnLayoutClosed(); } } } ObjectAnimator positionAnimator = ObjectAnimator.ofFloat(card, "y", this.getY(), 0); positionAnimator.setDuration(0); positionAnimator.start(); direction = Direction.NONE; return true; } direction = Direction.NONE; } return true; } return false; } public void setOnLayoutCloseListener(OnLayoutCloseListener closeListener) { this.listener = closeListener; } public void lock() { isLocked = true; } public void unLock() { isLocked = false; }

LayoutParam

使用此代码进行card.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); min_height

之间的滚动视图
max_height

2 个答案:

答案 0 :(得分:1)

int pressedx,pressedy;
    int viewMariginX,viewMariginY;  

@Override
public boolean onTouch(View v, MotionEvent event) {

    int currentx=(int) event.getRawX();
    int currenty=(int) event.getRawY();


//get Layout Param of your cardView 

    FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) v.getLayoutParams();

    switch(event.getAction())
    {

    case MotionEvent.ACTION_DOWN :

        pressedx=currentx;
        pressedy=currenty;

        viewMariginX=layoutParams.leftMargin;
        viewMariginY=layoutParams.topMargin;
        break;


    case MotionEvent.ACTION_MOVE : 

        int diffx=currentx-pressedx;
        int diffy=currenty-pressedy;

        int marginx=viewMariginX+diffx;
        int marginy=viewMariginY+diffy;


        layoutParams.leftMargin=marginx;
        layoutParams.topMargin=marginy;     
        v.setLayoutParams(layoutParams);          
        break;

    case MotionEvent.ACTION_UP : 

        int diffx2=currentx-pressedx;
        int diffy2=currenty-pressedy;

        int marginx2=viewMariginX+diffx2;
        int marginy2=viewMariginY+diffy2;


        layoutParams.leftMargin=marginx2;
        layoutParams.topMargin=marginy2;            
        v.setLayoutParams(layoutParams);    
        break;
    }

    return true;
}

您的参考资料与我几天前所做的相似。

它需要两个位置的差异,并将它们从左侧和顶部添加到当前的视图边距。

您可以通过保存这些边距值来保留视图的位置。

注意:您必须处理MAX和MIN Bounds

希望它可以帮助你...

<强>更新: 1) 根据需要在onTouchListners上附加任意数量的卡片视图

cardview.setOnTouchListener(本); cardview1.setOnTouchListener(本);

OnTouch(View v,MotionEvent事件) 将触摸事件调度到视图时调用。这允许侦听器有机会在目标视图之前做出响应。

由OnTouchListener中的onTouch(...)指定 参数: v:已分派触摸事件的视图。 event:包含有关事件的完整信息的MotionEvent对象。 通过文档。

将onTouch中的cardview更改为v

从你的问题

FrameLayout.LayoutParams layoutParams =(FrameLayout.LayoutParams)v.getLayoutParams();

ObjectAnimator positionAnimator = ObjectAnimator.ofFloat(v,“y”,this.getY(),marginy);             positionAnimator.setDuration(0);             positionAnimator.start();

以相同的方法更改进一步的引用。

2)设置边界的问题很简单在更改位置之前进行条件检查。

抱歉说不好。

答案 1 :(得分:0)

这个动画:

ObjectAnimator positionAnimator = ObjectAnimator.ofFloat(card, "y", this.getY(), 0);

将垂直轴上的视图从this.getY() y位置移动到0(屏幕顶部)。

我看到您正在设置某些界限max_heightmin_height,但您并未以任何方式使用它们。

我不确定您的要求是什么,但您可以这样做:

ObjectAnimator positionAnimator = ObjectAnimator.ofFloat(card, "y", this.getY(), (Math.abs(this.getY() - min_height) < Math.abs(this.getY() - max_height))?min_height:max_height);

这样做的目的是根据最接近的对象将对象移动到min_heightmax_height

此视图似乎也会通过此调用this.setY(baseLayoutPosition + diffY); requestLayout();设置动画,您必须确保baseLayoutPosition + diffY在范围内,例如:

int amount = baseLayoutPosition + diffY;
this.setY(Math.min(max_height, Math.max(min_height, amount)));