绑定视图在RelativeLayout中拖动

在RelativeLayout里创build了一个可拖动的视图 。 但它似乎超越了RelativeLayout。

我只是想在ViewGroup里面做一个可拖动的View

这个视图可以根据屏幕draggable 。 它可以在RelativeLayout的边界之外拖动。 我怎么能限制它在RelativeLayout中保持可拖动。

CustomImageButton

 public class ImageButtonCustom extends ImageButton implements View.OnTouchListener{ float dX, dY; private RelativeLayout rootView; private ImageButtonCustom imageButtonCustom; private OnMoveListener onMoveListener; public ImageButtonCustom(Context context,RelativeLayout rootView){ super(context); this.rootView = rootView; init(); } public ImageButtonCustom(Context context) { super(context); init(); } public ImageButtonCustom(Context context, AttributeSet attrs) { super(context, attrs); init(); } public ImageButtonCustom(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init(){ imageButtonCustom = this; setImageResource(R.drawable.upper_left); setBackgroundColor(Color.TRANSPARENT); setOnTouchListener(this); /*RelativeLayout.LayoutParams rl = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); rl.addRule(RelativeLayout.ALIGN_BOTTOM);*/ rootView.addView(this); } @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: dX = v.getX() - event.getRawX(); dY = v.getY() - event.getRawY(); break; case MotionEvent.ACTION_UP: break; case MotionEvent.ACTION_POINTER_DOWN: break; case MotionEvent.ACTION_POINTER_UP: break; case MotionEvent.ACTION_MOVE: v.animate() .x(event.getRawX() + dX) .y(event.getRawY() + dY) .setDuration(0) .start(); //no use of ViewPositionUtil onMoveListener.onMove(new Position());//positionXY); break; } rootView.invalidate(); return true; } public void setOnMoveListener(OnMoveListener onMoveListener){ this.onMoveListener = onMoveListener; } public float getCenterX(){ return getX() + getWidth() / 2; } public float getCenterY(){ return getY() + getHeight() / 2; } public interface OnMoveListener{ void onMove(Position positionXY); } } 

编辑:

ImageButton是可拖动的,但它outside of parent限制它在其父级布局中拖动。

Solutions Collecting From Web of "绑定视图在RelativeLayout中拖动"

这是我以前的日记摘录。 希望对你有效。

 public class OnDragTouchListener implements View.OnTouchListener { /** * Callback used to indicate when the drag is finished */ public interface OnDragActionListener { /** * Called when drag event is started * * @param view The view dragged */ void onDragStart(View view); /** * Called when drag event is completed * * @param view The view dragged */ void onDragEnd(View view); } private View mView; private View mParent; private boolean isDragging; private boolean isInitialized = false; private int width; private float xWhenAttached; private float maxLeft; private float maxRight; private float dX; private int height; private float yWhenAttached; private float maxTop; private float maxBottom; private float dY; private OnDragActionListener mOnDragActionListener; public OnDragTouchListener(View view) { this(view, (View) view.getParent(), null); } public OnDragTouchListener(View view, View parent) { this(view, parent, null); } public OnDragTouchListener(View view, OnDragActionListener onDragActionListener) { this(view, (View) view.getParent(), onDragActionListener); } public OnDragTouchListener(View view, View parent, OnDragActionListener onDragActionListener) { initListener(view, parent); setOnDragActionListener(onDragActionListener); } public void setOnDragActionListener(OnDragActionListener onDragActionListener) { mOnDragActionListener = onDragActionListener; } public void initListener(View view, View parent) { mView = view; mParent = parent; isDragging = false; isInitialized = false; } public void updateBounds() { updateViewBounds(); updateParentBounds(); isInitialized = true; } public void updateViewBounds() { width = mView.getWidth(); xWhenAttached = mView.getX(); dX = 0; height = mView.getHeight(); yWhenAttached = mView.getY(); dY = 0; } public void updateParentBounds() { maxLeft = 0; maxRight = maxLeft + mParent.getWidth(); maxTop = 0; maxBottom = maxTop + mParent.getHeight(); } @Override public boolean onTouch(View v, MotionEvent event) { if (isDragging) { float[] bounds = new float[4]; // LEFT bounds[0] = event.getRawX() + dX; if (bounds[0] < maxLeft) { bounds[0] = maxLeft; } // RIGHT bounds[2] = bounds[0] + width; if (bounds[2] > maxRight) { bounds[2] = maxRight; bounds[0] = bounds[2] - width; } // TOP bounds[1] = event.getRawY() + dY; if (bounds[1] < maxTop) { bounds[1] = maxTop; } // BOTTOM bounds[3] = bounds[1] + height; if (bounds[3] > maxBottom) { bounds[3] = maxBottom; bounds[1] = bounds[3] - height; } switch (event.getAction()) { case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: onDragFinish(); break; case MotionEvent.ACTION_MOVE: mView.animate().x(bounds[0]).y(bounds[1]).setDuration(0).start(); break; } return true; } else { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: isDragging = true; if (!isInitialized) { updateBounds(); } dX = v.getX() - event.getRawX(); dY = v.getY() - event.getRawY(); if (mOnDragActionListener != null) { mOnDragActionListener.onDragStart(mView); } return true; } } return false; } private void onDragFinish() { if (mOnDragActionListener != null) { mOnDragActionListener.onDragEnd(mView); } dX = 0; dY = 0; isDragging = false; } } 

您可以使用以下设置:

 myView.setOnTouchListener(new OnDragTouchListener(myView)); 

或者直接在自定义视图的init方法中添加:

 setOnTouchListener(new OnDragTouchListener(this)); 

您应该使用rootView.getX()rootView.getY()作为左侧和顶部的bounderies和(rootView.getX() + rootView.getWidth())作为右侧和(rootView.getY() + rootView.getHeight())作为底部边界。

你必须在ACTION_MOVE情况下在onTouch()中编写你的边界逻辑。

希望这可以帮助。

在OnTouch中,您可以计算移动视图的位置

 case MotionEvent.ACTION_MOVE: v.animate() .x(event.getRawX() + dX) .y(event.getRawY() + dY) .setDuration(0) .start(); 

在移动之前,你应该检查x和y的边界。

 case MotionEvent.ACTION_MOVE: float x = event.getRawX() + dX; float y = event.getRawY() + dY; if (x > boundaryRight) x = boundaryRight; else if (x < boundaryLeft) x = boundaryLeft; if (y < boundaryTop) y = boundaryTop; else if (y > boundaryBottom) y = boundaryBottom; v.animate() .x(x) .y(y) .setDuration(0) .start(); 

并且要在运行时计算RelativeLayout的边界,您应该使用Runnable或Listener或类似的方法确定运行时Android视图的大小