Android移动ImageView

5

我在网上搜索了一个简单的解决方案,可以自由移动一个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个回答

3
根据谷歌的建议,如果您的目标是Android 3.0及以上版本,则可以使用DragListener
对于蜂巢之前的版本,您可以使用类似以下的内容:
// 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再次建议的这里


1

Here's the solution i got:

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轴上移动并检测是否向上或向下移动。这是通过将视图动画化到触摸上完成的,具有优点和缺点(缺点:很难检测视图在空间中的位置/优点:视图实际移动而不仅仅出现在其他地方),但对我来说效果最好且相当简单。 这里的目标是向上滑动视图并将其移到所需位置,同样地,向下滑动将其返回到原始位置,这是相对于屏幕大小实现的。 对我来说,代码相对简单且自我解释,但如果有任何不清楚的地方,请提问。

0

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

干杯。


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

}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接