Android Move ImageView

Busqué en la web una solución sencilla para mover libremente un ImageView . Finalmente encontré un código que produce el resultado perfecto:

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

Dado que realmente no sé cómo funciona mi código, quería ver si había mejores soluciones.

4 Solutions collect form web for “Android Move ImageView”

Como sugiere Google, si orientas las versiones de Android 3.0 y superiores, puedes usar un DragListener .

Para las versiones anteriores a Honeycomb, puedes usar algo como:

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

Como lo sugirió otra vez Google aquí .

Aquí está la solución que tengo:

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

Explicación: Sólo necesitaba movimiento en el eje y y dectección si se movía hacia arriba o hacia abajo. Es abajo animando la vista al tacto, la bruja tiene pros y contras (contra: es complicado detectar dónde está la vista en el espacio / pro: la vista se mueve y no parece estar en otro lugar) pero resultó funcionar mejor para Y es bastante simple. El objetivo aquí es deslizar la vista hacia arriba y llegar a un punto deseado, lo mismo que deslizar hacia abajo, volver a la posición original, esto se logra relativamente al tamaño de la pantalla. Para mí el código es relativamente simple y selfexplainatory, pero por favor pregunte si algo no está claro.

Ya que ha utilizado setTranslationX (), que es del nivel 11 de la API, es mejor utilizar DragListener. http://developer.android.com/guide/topics/ui/drag-drop.html

Esa es la solución de trabajo

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

aclamaciones.

  • Imagen de Android vista de la gravedad
  • Vista previa de la cámara Android estirada
  • ¿Es posible crear este tipo de vista personalizada en android?
  • Android: ¿Cómo hacer una vista previa de cámara en forma de círculo?
  • Cómo agregar un marcador pin en la vista de la imagen en android
  • Vista androide o surfaceView, ¿qué debo usar?
  • Obtener nuevo mapa de bits de imagen escalada y visible
  • Configurar la tipografía de la sugerencia en TextEdit
  • Reproducción de vídeo en un GLSurfaceView en lugar de SurfaceView
  • Vista de carrusel de imagen de Android (sentido como)
  • Imagen de mapa de bits sin memoria
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.