Android移动ImageView

时间:2013-12-20 15:01:14

标签: android image view touch move

我在网上搜索了一个简单的解决方案来自由移动ImageView。我终于找到了一些产生完美结果的代码:

public class MainActivity extends Activity implements View.OnTouchListener {

    private int _xDelta;
    private int _yDelta;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ImageView j = (ImageView)findViewById(R.id.j);

        j.setOnTouchListener(this);

    }

    public boolean onTouch(View view, MotionEvent event) {
        final int X = (int) event.getRawX();
        final int Y = (int) event.getRawY();
        ImageView j = (ImageView)findViewById(R.id.j);
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
                _xDelta = (int) (X - j.getTranslationX());
                _yDelta = (int) (Y - j.getTranslationY());
                break;
            case MotionEvent.ACTION_UP:
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                break;
            case MotionEvent.ACTION_POINTER_UP:
                break;
            case MotionEvent.ACTION_MOVE:
                RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view.getLayoutParams();

                j.setTranslationX(X - _xDelta);
                j.setTranslationY(Y - _yDelta);
                break;
        }

        return true;
    }}

由于我真的不知道我的代码是如何工作的,所以我想看看是否有更好的解决方案。

5 个答案:

答案 0 :(得分:3)

正如Google建议的那样,如果您定位Android 3.0及更高版本,则可以使用DragListener

对于pre-Honeycomb版本,您可以使用以下内容:

// The ‘active pointer’ is the one currently moving our object.
private int mActivePointerId = INVALID_POINTER_ID;

@Override
public boolean onTouchEvent(MotionEvent ev) {
    // Let the ScaleGestureDetector inspect all events.
    mScaleDetector.onTouchEvent(ev);

    final int action = MotionEventCompat.getActionMasked(ev); 

    switch (action) { 
    case MotionEvent.ACTION_DOWN: {
        final int pointerIndex = MotionEventCompat.getActionIndex(ev); 
        final float x = MotionEventCompat.getX(ev, pointerIndex); 
        final float y = MotionEventCompat.getY(ev, pointerIndex); 

        // Remember where we started (for dragging)
        mLastTouchX = x;
        mLastTouchY = y;
        // Save the ID of this pointer (for dragging)
        mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
        break;
    }

    case MotionEvent.ACTION_MOVE: {
        // Find the index of the active pointer and fetch its position
        final int pointerIndex = 
                MotionEventCompat.findPointerIndex(ev, mActivePointerId);  

        final float x = MotionEventCompat.getX(ev, pointerIndex);
        final float y = MotionEventCompat.getY(ev, pointerIndex);

        // Calculate the distance moved
        final float dx = x - mLastTouchX;
        final float dy = y - mLastTouchY;

        mPosX += dx;
        mPosY += dy;

        invalidate();

        // Remember this touch position for the next move event
        mLastTouchX = x;
        mLastTouchY = y;

        break;
    }

    case MotionEvent.ACTION_UP: {
        mActivePointerId = INVALID_POINTER_ID;
        break;
    }

    case MotionEvent.ACTION_CANCEL: {
        mActivePointerId = INVALID_POINTER_ID;
        break;
    }

    case MotionEvent.ACTION_POINTER_UP: {

        final int pointerIndex = MotionEventCompat.getActionIndex(ev); 
        final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex); 

        if (pointerId == mActivePointerId) {
            // This was our active pointer going up. Choose a new
            // active pointer and adjust accordingly.
            final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
            mLastTouchX = MotionEventCompat.getX(ev, newPointerIndex); 
            mLastTouchY = MotionEventCompat.getY(ev, newPointerIndex); 
            mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex);
        }
        break;
    }
    }       
    return true;
}

再次由Google here建议。

答案 1 :(得分:1)

这是我得到的解决方案:

private float xCoOrdinate, yCoOrdinate;

         view.setOnTouchListener(new View.OnTouchListener() {

            Float y1 = 0f, y2 = 0f;

            @Override
            public boolean onTouch(View v, MotionEvent event) {

                Point size = new Point();
            getWindowManager().getDefaultDisplay().getSize(size);        

                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        //xCoOrdinate = view.getX() - event.getRawX();
                        yCoOrdinate = view.getY() - event.getRawY();
                        Float puffer = 0f;
                        y1 = event.getRawY();

                        break;
                    case MotionEvent.ACTION_MOVE:
                        view.animate().y(event.getRawY() + yCoOrdinate).setDuration(0).start();
                        //view.animate().x(event.getRawX() + xCoOrdinate).y(event.getRawY() + yCoOrdinate).setDuration(0).start();
                        break;
                    case MotionEvent.ACTION_UP:
                        y2 = event.getRawY();
                        Float dy = (y2 - y1);


                        if (dy < 0) { 
                            //moved up
                            view.animate().y(size.y / 100 * -40).setDuration(100).start();
                        } else if (dy > 0) {  
                            // moved down
                            view.animate().y(size.y / 2 - view.getHeight() / 2).setDuration(100).start();  
                        }

                        break;
                }

                return false;
            }
        });

说明:如果向上或向下移动,我只需要在y轴上运动和检测。通过将视图设置为触摸动画来完成,女巫有优点和反对(反对:它很复杂,可以检测到视图在空间/专业中的位置:视图实际上移动并且看起来不仅仅是在其他地方)但结果却是为我工作最好,很简单。 这里的目标是向上滑动视图并将其移动到所需的位置,与向下滑动一样,回到原始位置,这与屏幕尺寸相关。 对我而言,代码相对简单且易于解释,但请问是否有任何不清楚的地方。

答案 2 :(得分:0)

由于您使用了来自API级别11的setTranslationX(),因此最好使用DragListener。 http://developer.android.com/guide/topics/ui/drag-drop.html

答案 3 :(得分:0)

这是有效的解决方案

public boolean onTouch(View view, MotionEvent event) {
final int X = (int) event.getRawX();
final int Y = (int) event.getRawY();
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
    RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams) view
            .getLayoutParams();

    _xDelta = X - lParams.leftMargin;
    _yDelta = Y - lParams.topMargin;
    break;
case MotionEvent.ACTION_UP:
    break;
case MotionEvent.ACTION_POINTER_DOWN:
    break;
case MotionEvent.ACTION_POINTER_UP:
    break;
case MotionEvent.ACTION_MOVE:
    RelativeLayout.LayoutParams ParamsA = (RelativeLayout.LayoutParams) view
            .getLayoutParams();
    ParamsA.leftMargin = X - _xDelta;
    ParamsA.topMargin = Y - _yDelta;
    ParamsA.rightMargin = -250;
    ParamsA.bottomMargin = -250;

    for (int i = 0; i < balls.size(); i++) {
        if (balls.get(i).getTag() != view.getTag()) {
            RelativeLayout.LayoutParams ParamsB = (RelativeLayout.LayoutParams) balls
                    .get(i).getLayoutParams();

            Rect b = new Rect(ParamsB.leftMargin,ParamsB.topMargin,ParamsB.rightMargin,ParamsB.bottomMargin);
            Rect a = new Rect(ParamsA.leftMargin,ParamsA.topMargin,ParamsA.rightMargin,ParamsA.bottomMargin);


            if(a.intersect(b))
            {
                Toast.makeText(getApplicationContext(), "Collision Detected", Toast.LENGTH_SHORT).show();
            }
        }

    }

    view.setLayoutParams(ParamsA);
    break;
}
// _root.invalidate();
return true;
}

欢呼声。

答案 4 :(得分:0)

正在工作

public class MainActivity extends AppCompatActivity {
ImageView imageView;
float xDown = 0;
float yDown = 0;

@SuppressLint("ClickableViewAccessibility")
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    imageView = findViewById(R.id.subview);
    imageView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getActionMasked()) {
                case MotionEvent.ACTION_DOWN:
                    xDown = event.getX();
                    yDown = event.getY();
                    break;
                case MotionEvent.ACTION_MOVE:
                    float moveX,moveY;
                    moveX = event.getX();
                    moveY = event.getY();

                    float distanceX = moveX -xDown;
                    float distanceY  = moveY -yDown;
                    imageView.setX(imageView.getX()+distanceX);
                    imageView.setY(imageView.getY()+distanceY);
                    break;
            }
            return true;
        }
    });
}

}