
其实除了执行父对象的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(); } }