¿Cómo manejar el toque fuera de la vista en Android?
He encontrado la implementación de "Undo Bar" utilizada en la aplicación de Gmail para Android. "UndoBar" es básicamente una vista que se muestra en la parte superior del diseño.
Desafortunadamente no es completa – no tiene funcionalidad de despedir la barra al tocar la pantalla fuera de la barra.
- Honeycomb Gmail Como Aplicación
- Obtener el nombre de usuario principal de la cuenta de gmail en Android <2.0
- Alternar el cajón de navegación a través del título de la barra de acciones
- ¿Cómo obtener el nombre y apellido en android?
- Android + gmail + feed + obtener TODOS los correos
He implementado FrameLayout
que anula onInterceptTouchEvent
para manejar la barra de despedir, pero tocar la barra de acción no hace nada.
¿Hay alguna manera de manejar estos eventos desde la barra de acción?
Abajo hay una imagen con "UndoBar" mostrado. Lo que quiero lograr para manejar el tacto en la barra de acción representada por punto rojo.
- ¿Cómo mostrar el ActionBar normal y dividido?
- La aplicación de Android Gmail no procesa la imagen de fondo en el correo electrónico HTML
- aplicación de gmail para Android como las conversaciones
- ¿Dónde puedo encontrar el código fuente para las aplicaciones de gmail, facebook y twitter para Android? ¿Son incluso de código abierto?
- getAuthToken no llama a AccountManagerCallback
- Cómo enviar correo electrónico con un enlace para abrir la aplicación de Android
- Crear grupo de contactos de gmail en android
- ProgressBar en una ActionBar, como la aplicación de GMail con Refresh
Trate de reemplazar dispatchTouchEvent de su actividad.
dispatchTouchEvent(MotionEvent event){ int x= event.getRawX(); int y= event.getRawY(); if(/*check bounds of your view*/){ // set your views visiblity to gone or what you want. } //for prevent consuming the event. return super().dispatchTouchEvent(event); }
actualizar
dispatchTouchEvent(MotionEvent event){ int x= event.getRawX(); int y= event.getRawY(); return super().dispatchTouchEvent(event)||[YourView].onTouch(event); }
Para capturar eventos táctiles para toda la pantalla, incluyendo el ActionBar, agregue una vista a la ventana.
View overlayView = new View(this); WindowManager.LayoutParams p = new WindowManager.LayoutParams(); p.gravity = Gravity.TOP; p.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL; p.token = overlayView.getWindowToken(); overlayView.setOnTouchListener(new OnTouchListener() { public boolean onTouch(View view, MotionEvent event) { // Get the action bar int actionBarHeight = actionBar.getHeight(); if ((event.getAction() == MotionEvent.ACTION_DOWN) && (event.getRawY() < actionBarHeight)) { // Touch inside the actionBar so let's consume it // Do something return true; } return false; } }); WindowManager mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE); mWindowManager.addView(overlayView, p);
Espero que esto ayude.
¿Has probado un onTouchEvent
en tu FrameLayout ..?
No lo he probado, pero creo que tiene sentido para mí que en caso de MotionEvent
en esa acción ACTION_OUTSIDE
disposición debe ser despedido.
Intente lo siguiente.
public boolean onTouchEvent(MotionEvent event) { if(event.getAction() == MotionEvent.ACTION_OUTSIDE){ undoBar.setVisibility(View.GONE); } return true; }
Hay 2 posibles soluciones.
Como mencioné en los comentarios, puedes implementar un listener de scroll en tu ListView
y simple llamado hideUndoBar(true)
en el scroll más leve.
O
Puede modificar el UndoBarController
. Notará que la barra de deshacer es simplemente un View
slap un OnFocusChange
escucha en la View
en el constructor y en el método show setFocus a la vista.
En su verificación OnFocusChange
para ver si la vista ha perdido el foco y llame a hideUndoBar(true)
.
Actualizar
He creado un Gist aquí https://gist.github.com/atgheb/5551961 que muestra cómo cambiar el UndoBarController
para agregar la característica donde se oculta cuando pierde el foco.
No lo he probado pero no veo por qué no funcionará.
params = new WindowManager.LayoutParams( WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_PHONE, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL|WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, PixelFormat.TRANSPARENT);
Lo que realmente necesita es:
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL|WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
La documentación dice:
Indicador de ventana: si ha configurado FLAG_NOT_TOUCH_MODAL, puede configurar este indicador para que reciba un solo movimiento especial con la acción MotionEvent.ACTION_OUTSIDE para los toques que se producen fuera de su ventana.
Puede obtener todos los eventos táctiles en su Activity
mediante el código siguiente. Supongo que este código obtendría los toques de ActionBar
también.
public class MainActivity extends Activity { ... // This example shows an Activity, but you would use the same approach if // you were subclassing a View. @Override public boolean onTouchEvent(MotionEvent event){ int action = MotionEventCompat.getActionMasked(event); switch(action) { case (MotionEvent.ACTION_DOWN) : Log.d(DEBUG_TAG,"Action was DOWN"); return true; case (MotionEvent.ACTION_MOVE) : Log.d(DEBUG_TAG,"Action was MOVE"); return true; case (MotionEvent.ACTION_UP) : Log.d(DEBUG_TAG,"Action was UP"); return true; case (MotionEvent.ACTION_CANCEL) : Log.d(DEBUG_TAG,"Action was CANCEL"); return true; case (MotionEvent.ACTION_OUTSIDE) : Log.d(DEBUG_TAG,"Movement occurred outside bounds " + "of current screen element"); return true; default : return super.onTouchEvent(event); } }
- Cómo hacer referencia de dibujable a estilo
- El emulador de Genymotion no se iniciará. Se queda para siempre en la pantalla "black and white"