防止图像视图在触摸和旋转时重叠

时间:2017-07-06 10:56:51

标签: android imageview

在我正在处理的应用中,相对布局中有2个单独的图像视图。我想让两个图像都可移动和可旋转,以响应我的活动的XML给定的动作事件:

<RelativeLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:app="http://schemas.android.com/apk/res-auto"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 tools:context="com.example.vishalbisht.dragfeature.MainActivity">

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentStart="true"
    android:id="@+id/Recycle"
    android:layout_alignParentLeft="true" />
<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/Ring"
    android:layout_alignParentEnd="true"
    android:layout_alignParentRight="true" />

</RelativeLayout>

虽然程序部分是:

public class MainActivity extends AppCompatActivity implements View.OnTouchListener {

ImageView jwl,rlo;
private final String TAG="DRAGFEATURE";
String Mode;
Bitmap bitmap,rotaBitmap;
BitmapDrawable bdr;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    jwl= (ImageView) findViewById(R.id.Recycle);
    rlo= (ImageView) findViewById(R.id.Ring);
    jwl.setImageResource(R.drawable.icon);
    rlo.setImageResource(R.drawable.ring);
    jwl.setOnTouchListener(this);
    rlo.setOnTouchListener(this);
}

@Override
public boolean onTouch(View v, MotionEvent event) {
    int eId = event.getActionMasked();
    Mode = "Move";
    switch (eId) {
        case MotionEvent.ACTION_MOVE:
                Log.v(TAG,"move image");
                drag(v, event);
                break;
        case MotionEvent.ACTION_DOWN:
                r = r + 13;
                rotate(v);
                break;
        default:break;
    }
    if (v != jwl && v != rlo)
        Log.v(TAG,"Not Valid");

    return true;
}

private int r =2;

private void rotate(View v) {
    if(v==jwl)
        bitmap=BitmapFactory.decodeResource(getResources(),R.drawable.icon);
    else
        bitmap=BitmapFactory.decodeResource(getResources(),R.drawable.ring);
    int w = bitmap.getWidth();
    int h = bitmap.getHeight();
    Matrix matrix = new Matrix();
    matrix.preRotate(-r);
    rotaBitmap = Bitmap.createBitmap(bitmap, 0, 0, w, h, matrix,true);
    bdr = new BitmapDrawable(rotaBitmap);
    if(v==jwl)
        jwl.setImageDrawable(bdr);
    else
        rlo.setImageDrawable(bdr);
}

private void drag(View v, MotionEvent event) {
    RelativeLayout.LayoutParams mParams = (RelativeLayout.LayoutParams) jwl.getLayoutParams();
    Log.v(TAG,"Start of Move");
    int x = (int) event.getRawX();
    int y = (int) event.getRawY();
    mParams.leftMargin = x - 150;
    mParams.topMargin = y - 210;
    if(v==jwl)
        jwl.setLayoutParams(mParams);
    else
        rlo.setLayoutParams(mParams);

 }
}

当我触摸或拖动左图像(回收)然后它很好但是当我点击Ring然后两个图像重叠并一起移动/旋转。为什么会发生这种情况以及如何解决?

2 个答案:

答案 0 :(得分:1)

    @Override
    public boolean onTouch(View view, MotionEvent event) {
        int pointerCount = event.getPointerCount();
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
//                downCounter++;
//                Log.v("","Action Down"+downCounter);

                startClickTime = Calendar.getInstance().getTimeInMillis();

                dX = view.getX() - event.getRawX();
                dY = view.getY() - event.getRawY();

                final float rawX = event.getRawX();
                final float rawY = event.getRawY();

                // Remember where we started
                mLastTouchX = rawX;
                mLastTouchY = rawY;
                break;

            case MotionEvent.ACTION_MOVE:
//                moveCounter++;
//                Log.v("", "Action Move "+moveCounter);
                if (pointerCount == 1) {

                    final float x1 = event.getRawX();
                    final float y1 = event.getRawY();

                    // Calculate the distance moved
                    final float dx = x1 - mLastTouchX;
                    final float dy = y1 - mLastTouchY;

                    // Make sure we will still be the in parent's container
                    Rect parent = new Rect(0, 0, root.getWidth(), root.getHeight());

                    //Find what the bounds of view will be after moving
                    int newLeft = (int) (view.getX() + dx),
                            newTop = (int) (view.getY() + dy),
                            newRight = newLeft + view.getWidth(),
                            newBottom = newTop + view.getHeight();

                    if (!parent.contains(newLeft, newTop, newRight, newBottom)) {
                        Log.v("", "Out of Bounds");
                    } else {
                        // Move the object
                        view.animate().
                                x(x1 + dX).
                                y(y1 + dY).
                                setDuration(0).
                                start();
                        // Remember this touch position for the next move event
                        mLastTouchX = x1;
                        mLastTouchY = y1;
                        // Invalidate to request a redraw
                        root.invalidate();
                        break;
                    }
                }
//                if(mode==2)
                if (pointerCount == 2)
                {
                    long clickDuration = Calendar.getInstance().getTimeInMillis() - startClickTime;
                    if(clickDuration > MAX_CLICK_DURATION) {
                        //Log.v(TAG, "for rotation");

                        float degree = rotation(event);

                        //Log.v(TAG, "setting at angle" + degree);

                        view.setRotation(view.getRotation() + degree);
                        break;

                    }
                }
                break;

            case MotionEvent.ACTION_UP:
//                upCounter++;
//                Log.v(TAG,"Action Up"+upCounter);


           /* case MotionEvent.ACTION_POINTER_DOWN:
                Log.v(TAG, "ACTION POINTER DOWN");
                if (pointerCount == 2) {
                    flagFirstTouch = 1;
                }
                break;*/

        }
        return true;
    }

我用这个来解决我的问题,希望这对某人有所帮助。

此外,将两个图像视图保存在父RelativeLayout内的单独frameLayouts中.frameLayouts可以具有高度和宽度的属性wrap_content

答案 1 :(得分:0)

更改布局xml如下:

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentStart="true"
    android:id="@+id/Recycle"
    android:layout_alignParentLeft="true" />
<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/Ring"
    android:layout_toRightOf="@+id/Recycle"
    android:layout_alignParentEnd="true"
    android:layout_alignParentRight="true" />