I have created a draggable view inside RelativeLayout. But it seems to go beyond the RelativeLayout.
我只是想让一个 View 可以在 ViewGroup 中拖动
而且这个 View 是 draggable
according to Screen.并且它可以拖动到 RelativeLayout 的边界之外。我怎样才能限制它在 RelativeLayout 中保持可拖动。
自定义图片按钮
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 是可拖动的,但它位于父布局之外
。限制它在其父布局内拖动。
最佳答案
这是我旧日记的节选。希望它对你有用。
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));
或者直接在自定义 View 的 init
方法中添加:
setOnTouchListener(new OnDragTouchListener(this));
关于android - 绑定(bind)一个 View 以在 RelativeLayout 中拖动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38999891/