其实除了执行父对象的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();
}
}
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.