Vista de desplazamiento de Android en evento táctil

Me gustaría mover dos vistas diferentes en mi diseño, para que un usuario puede mostrarlo como sus deseos.

Hasta ahora he hecho el siguiente código para manejar el evento de toque:

this.viewEvent.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent event) { final int y = (int) event.getRawY(); RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) view.getLayoutParams(); switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: element.setEventY(y - params.topMargin); break; case MotionEvent.ACTION_UP: viewGroup.invalidate(); break; case MotionEvent.ACTION_POINTER_DOWN: case MotionEvent.ACTION_POINTER_UP: break; case MotionEvent.ACTION_MOVE: params.topMargin = y - element.getEventY(); params.bottomMargin = screenHeight - view.getHeight() - params.topMargin; // Avoid out of screen if (params.topMargin < 0) return true; // Apply changes view.setLayoutParams(params); break; } return true; } }); 

element es una instancia de un objeto personalizado para manejar la posición. screenHeight es la altura de la pantalla dada por la clase Display .

Soy capaz de mover el elemento, pero está parpadeando cuando lo toco y una vez que pongo el dedo, la vista desaparece. Ni siquiera puedo recuperarla, es sólo fuera de la pantalla.

¿Hice algo mal?

Gracias por tu ayuda

Utilice el siguiente código para realizar un simple Touch to move :

 layout_counter.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent event) { if (currentState != State.EDIT_MOVE) return false; FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) view.getLayoutParams(); if (view.getId() != R.id.layout_counter) return false; switch (event.getAction()) { case MotionEvent.ACTION_MOVE: params.topMargin = (int) event.getRawY() - view.getHeight(); params.leftMargin = (int) event.getRawX() - (view.getWidth() / 2); view.setLayoutParams(params); break; case MotionEvent.ACTION_UP: params.topMargin = (int) event.getRawY() - view.getHeight(); params.leftMargin = (int) event.getRawX() - (view.getWidth() / 2); view.setLayoutParams(params); break; case MotionEvent.ACTION_DOWN: view.setLayoutParams(params); break; } return true; } }); 

Donde layout_counter es la vista que desea mover.

No olvide poner sus elementos movibles en un FrameLayout

He creado la biblioteca, que mueve la vista:

  • Para API inferior a JellyBean (16), modifica los márgenes de la vista dentro de su contenedor principal
  • Para API JellyBean y superior, modifica la posición de vista absoluta dentro de su contenedor principal

Sólo tiene que añadir la dependencia:

 dependencies { compile 'com.scalified:viewmover:1.1.0' } 

Más información que puedes encontrar en GitHub

Proporcionaré una solución alternativa para aquellos que usen el diseño relativo, por ejemplo.

 import android.app.Activity; import android.os.Bundle; import android.view.MotionEvent; import android.view.View; import android.view.ViewTreeObserver; import android.widget.ImageView; import android.widget.RelativeLayout; public class MainActivity extends Activity implements View.OnTouchListener { private int _xDelta; private int _yDelta; private int _rightMargin; private int _bottomMargin; private ImageView _floatingView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); this._floatingView = (ImageView) findViewById(R.id.textView); this._floatingView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { if (_floatingView.getViewTreeObserver().isAlive()) _floatingView.getViewTreeObserver().removeOnPreDrawListener(this); updateLayoutParams(_floatingView); return false; } }); this._floatingView.setOnTouchListener(this); } private void updateLayoutParams(View view) { this._rightMargin = -view.getMeasuredWidth(); this._bottomMargin = -view.getMeasuredHeight(); RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(view.getMeasuredWidth(), view.getMeasuredHeight()); layoutParams.bottomMargin = this._bottomMargin; layoutParams.rightMargin = this._rightMargin; view.setLayoutParams(layoutParams); } @Override public boolean onTouch(View view, MotionEvent event) { if (view == this._floatingView) { 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(); this._xDelta = X - lParams.leftMargin; this._yDelta = Y - lParams.topMargin; break; case MotionEvent.ACTION_MOVE: RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view.getLayoutParams(); layoutParams.leftMargin = X - this._xDelta; layoutParams.topMargin = Y - this._yDelta; layoutParams.rightMargin = this._rightMargin; layoutParams.bottomMargin = this._bottomMargin; view.setLayoutParams(layoutParams); break; } return true; } else { return false; } } } 
  • Cómo codificar para multitouch
  • Cómo hacer la detección de objetos en opengl Android?
  • Vista de imagen en movimiento con evento táctil
  • ¿Cómo transferir eventos táctiles a la vista inferior en un RelativeLayout?
  • Simulando el tacto usando ADB
  • Enlace de evento de toque de Android WebView
  • Android ListView áreas parciales presionables
  • ¿Alguien sabe lo que significa la salida de getevent?
  • Sensibilidad táctil de Android SeekBar
  • Navegador Android: touchcancel está siendo disparado aunque touchmove tiene preventDefault
  • ¿Por qué es el evento touchstart después de hacer clic?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.