Detectar clics largos en una vista personalizada?
Tengo una vista personalizada que amplía FrameLayout
y implementa ScaleGestureDetector.OnScaleGestureListener
. Esta vista, como el nombre de la clase sugiere, es zoomable + pannable. Heres la clase de vistas personalizadas: https://gist.github.com/Orbyt/23c82ce9002df6c318d4
He estado tratando de encontrar una forma de detectar clics largos en esta vista. Sé que, por lo general, podría hacer algo como esto en la Actividad:
- Cómo establecer el ancho que es igual a otro widget en android
- MuPDF para Android: opción para el fragmento en su lugar Actividad
- Forzar el reajuste en un grupo de vista incluyendo todos sus hijos
- Cambiar el ancho y la altura de la vista personalizada en Android
- Crash al devolver el fragmento como una pestaña. Ver con la misma ID
GestureDetector mGestureDetector = new GestureDetector(this, this); mZoomableLayout.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return mGestureDetector.onTouchEvent(event); } }); mGestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() { @Override public void onLongPress(MotionEvent e) { // do tasks here } });
Usando esto, el View ya no es zoomable, presumiblemente porque intercepta todos los eventos onTouch en lugar de la implementación dentro de la clase Views.
Así que mi pregunta es, ¿cuál es la manera más limpia de detectar clics largos en esta vista?
- Implementar vista como ver paginador
- Eventos de desplazamiento de HTML en un WebView de Android que está dentro de un ScrollView
- ¿Cómo obtener el contenido de una pestaña dentro de TabHost?
- En la vista Web de Android, ¿puedo modificar el DOM de una página web?
- ¿Es posible acortar los nombres de vista personalizada?
- ¿Cómo aplicar una transparencia (enfoque?) Al pulsar cualquier elemento (como lo hace Google)?
- Cambiar el contenido de la vista de la actividad dinámicamente
- ViewStub vs View.GONE vs Inflate vs ViewSwitcher
Tuve un pinch zoom círculo en el que he detectado el clic normal y click.Code largo snippet se da a continuación. En esto he detectado un clic largo y normal haga clic en el intervalo de tiempo entre MotionEvent.ACTION_DOWN y MotionEvent.ACTION_UP.
Que esto te ayude.
private static final int MAX_CLICK_DURATION = 200; private float mScaleFactor = 1.0000000f; private long mStartClickTime; @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); boolean right = x > (screenWidthPX / 2 + ((mLayoutHeight / 4) + 20) * mScaleFactor); boolean left = x < (screenWidthPX / 2 - ((mLayoutHeight / 4) + 20) * mScaleFactor); boolean top = y > (mLayoutHeight / 2 + ((mLayoutHeight / 4) + 20) * mScaleFactor); boolean bottom = y < (mLayoutHeight / 2 - ((mLayoutHeight / 4) + 20) * mScaleFactor); if (event.getPointerCount() > 1) { if (left || right || top || bottom) { // You may not need this condtion, I needed this because I had custom view of pinch zoom circle and, this condition detects the touch at outer area of circle. } else { mScaleGestureDetector.onTouchEvent(event); } } else { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: { mStartClickTime = Calendar.getInstance().getTimeInMillis(); break; } case MotionEvent.ACTION_UP: { long clickDuration = Calendar.getInstance().getTimeInMillis() - mStartClickTime; if (clickDuration < MAX_CLICK_DURATION) { if (left || right || top || bottom) { } else { Toast.makeText(mContext, "Normal CLick Detected", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(mContext, "Long CLick Detected", Toast.LENGTH_SHORT).show(); } } } } return true; }
Ok, lo siento, no entendí su problema en absoluto. Ahora en su MainActivity:
public yourMainConstructor() { [...] GestureDetector sgd; sgd = new GestureDetector(context,new ScaleListener()); [...] } class ScaleListener extends GestureDetector.SimpleOnGestureListener { @Override public void onLongPress(MotionEvent e) { super.onLongPress(e); } }
Entonces anula en su clase principal onTouchEvent ()
@Override public boolean onTouchEvent(MotionEvent event) { sgd.onTouchEvent(event); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: [...] } }
En primer lugar, necesitará utilizar el toque para distinguir entre el movimiento real y el movimiento involuntario del dedo del usuario (ver ACTION_MOVE). Segundo, si está extendiendo FrameLayout
, es más limpio reemplazar onTouchEvent
lugar de this.setOnTouchListener
en init()
.
Agregue variables a su vista personalizada:
private final Handler mHandler = new Handler(); private ScaleGestureDetector mScaleDetector; private int mTouchSlop; private Runnable mLongPressed = new Runnable() { public void run() { Log.i(TAG, "Long press!"); //Do your long press stuff here. } };
Dentro de init()
:
mScaleDetector = new ScaleGestureDetector(context, this); mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
En la instrucción switch:
switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: //Whatever you were doing previously here mHandler.postDelayed(mLongPressed, ViewConfiguration.getLongPressTimeout()); break; case MotionEvent.ACTION_MOVE: if (mode == Mode.DRAG) { dx = motionEvent.getX() - startX; dy = motionEvent.getY() - startY; if(Math.abs(dx) > mTouchSlop || Math.abs(dy) > mTouchSlop) { //Actual movement mHandler.removeCallbacks(mLongPressed); } else { //Below touch slop, not a movement dx = 0; dy = 0; } } break; case MotionEvent.ACTION_POINTER_DOWN: mHandler.removeCallbacks(mLongPressed); //Whatever you were doing previously here break; case MotionEvent.ACTION_POINTER_UP: mHandler.removeCallbacks(mLongPressed); //Whatever you were doing previously here break; case MotionEvent.ACTION_UP: mHandler.removeCallbacks(mLongPressed); //Whatever you were doing previously here break; } //Whatever you were doing previously here
Ahora las tres funcionalidades están funcionando.
Si el punto del tecleo largo es necesario hacer una clase abstracta que implemente Runnable
con los flotadores xyy los llene en ACTION_DOWN
, después utiliza coordenadas en el run()
- Proyecto de la librería Android com.android.dex.DexException: Varios archivos dex definen Lcom / google / gson / JsonSerializer
- Cordova / error de compilación jónico (a veces): no tienen el entorno requerido