绑定视图以在RelativeLayout内拖动 [英] Bound a View to drag inside RelativeLayout

查看:114
本文介绍了绑定视图以在RelativeLayout内拖动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在RelativeLayout中创建了一个可拖动视图.但这似乎超出了RelativeLayout.

I have created a draggable view inside RelativeLayout. But it seems to go beyond the RelativeLayout.

我只想在ViewGroup中创建一个可拖动的视图

根据屏幕,此视图为draggable.而且它可以拖动到RelativeLayout的边界之外.如何限制它在RelativeLayout中保持可拖动状态.

And this view is draggable according to Screen. And it is draggable beyond the boundaries of RelativeLayout. How could I restrict it to stay draggable within 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);
    }
}

图像按钮是可拖动的,但它会变为outside of parent.限制以将其拖动到其父版式中.

The ImageButton is Draggable but it goes outside of parent .Restrict it to drag within it's parent Layout.

推荐答案

以下是我的旧日记的摘录.希望它对您有用.

Here's an extract from my old diaries. Hope it works for you.

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;
    }
}

您可以使用以下命令进行设置:

And you can set it using:

myView.setOnTouchListener(new OnDragTouchListener(myView));

或通过直接在自定义视图"的init方法中添加它:

Or by adding this directly in init method of your Custom View:

setOnTouchListener(new OnDragTouchListener(this));

这篇关于绑定视图以在RelativeLayout内拖动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆