2013-12-20 18 views
5

Ich suchte im Internet nach einer einfachen Lösung, um eine ImageView frei zu bewegen. Schließlich fand ich einige Code, der das perfekte Ergebnis produziert:Android 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; 
    }} 

Da ich nicht wirklich wissen, wie mein Code funktioniert, ich wollte sehen, ob es besser waren Lösungen.

Antwort

1

Hier ist die Lösung, die ich bekam:

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

Erläuterung: Ich brauchte nur Bewegung auf der y-Achse und Dectection wenn oder nach unten bewegt. Es ist unten, indem man den Blick auf den Touch animiert, der Pros und Kontras hat (contra: es ist kompliziert zu erkennen, wo die Ansicht im Raum ist/Pro: Die Ansicht bewegt sich tatsächlich und scheint nicht woanders zu sein), aber es hat sich als am besten erwiesen mir und ist ganz einfach. Das Ziel hier ist, die Ansicht nach oben zu wischen und sie an die gewünschte Stelle zu bringen, genau wie beim Wischen nach unten, zurück zur ursprünglichen Position, dies wird relativ zur Bildschirmgröße erreicht. Für mich ist der Code relativ einfach und selblexplinatorisch, aber bitte fragen Sie, ob etwas unklar ist.

3

Wie von Google vorgeschlagen, könnten Sie mit Android 3.0 und höher eine DragListener verwenden.

Für Pre-Honeycomb-Versionen Sie so etwas wie verwenden:

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

als wieder vorgeschlagen von Google here.

0

Diese Lösung

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

prost arbeitet.