ViewDragHelper 在父对象执行 requestLayout()后可拖动的子对象会复位,这个问题怎么解决呢?

2015-02-17 01:50:03 +08:00
 q84629462

其实除了执行父对象的requestLayout以外,执行addView也会造成已拖动到其它位置的子view的复位

问题的关键在于测试代码里的addChild方法和callback的onViewReleased里的requestLayout
必然会造成已拖动过的子view(addChild添加的TextView)复位到0,0坐标
http://stackoverflow.com/questions/22865291/why-is-view-dragged-with-viewdraghelper-reset-to-its-original-position-on-layout
搜到一个同样的问题,但vote 2的答案似乎不太适合我这个随意添加子view的需求
特来求救。

测试代码
public class DragViewLayout extends FrameLayout {
private ViewDragHelper mDragHelper;
private ViewDragHelper.Callback callback = new ViewDragHelper.Callback() {
@Override
public boolean tryCaptureView(View child, int pointerId) {
return true;
}

@Override
    public void onViewReleased(View releasedChild, float xvel, float yvel) {
        super.onViewReleased(releasedChild, xvel, yvel);
        requestLayout();
    }

    @Override
    public int clampViewPositionHorizontal(View child, int left, int dx) {
        final int leftBound = getPaddingLeft();
        final int rightBound = getWidth() - child.getMeasuredWidth();
        final int newLeft = Math.min(Math.max(left, leftBound), rightBound);
        ViewHelper.setX(child, newLeft);
        return newLeft;
    }

    @Override
    public int clampViewPositionVertical(View child, int top, int dy) {
        final int topBound = getPaddingTop();
        final int bottomBound = getHeight() - child.getMeasuredHeight();
        final int newTop = Math.min(Math.max(top, topBound), bottomBound);
        ViewHelper.setY(child, newTop);
        return newTop;
    }
};

public DragViewLayout(Context context) {
    super(context);
}

public DragViewLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public DragViewLayout(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}

@Override
protected void onAttachedToWindow() {
    super.onAttachedToWindow();
    mDragHelper = ViewDragHelper.create(this, 1.0f, callback);
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    final int action = MotionEventCompat.getActionMasked(ev);
    if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
        mDragHelper.cancel();
        return false;
    }
    return mDragHelper.shouldInterceptTouchEvent(ev);
}

@Override
public boolean onTouchEvent(MotionEvent ev) {
    mDragHelper.processTouchEvent(ev);
    return true;
}

public void addChild() {
    TextView v = new TextView(getContext());
    v.setPadding(20, 20, 20, 20);
    v.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
    v.setBackgroundColor(getContext().getResources().getColor(android.R.color.darker_gray));
    v.setText(System.currentTimeMillis() + "");
    addView(v);
}

public void clearChilds() {
    this.removeAllViewsInLayout();
}

}

6345 次点击
所在节点    Android
0 条回复

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/171423

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX