Cómo encontrar la vista de origen de un MotionEvent ACTION_CANCEL
¿Cómo puedo encontrar la vista que causa un MotionEvent ACTION_CANCEL? Tengo una vista "A" que está recibiendo ACTION_CANCEL y no quiero que eso suceda. En algún lugar, una vista "B" está "consumiendo" el MotionEvent. Espero que haya una manera de averiguar quién es "B" para poder solucionar esta falta de funcionalidad.
He intentado mirar a través de mi código para varios controladores OnTouchEvent () y OnInterceptTouchEvent () pero todavía no han encontrado un culpable.
- Android MotionEvent Puntero Indice Confusión
- Android cuál es la diferencia entre getAction () y getActionMasked () en MotionEvent
- OnInterceptTouchEvent nunca recibe action_move
- ¿Cuál es la diferencia entre ACTION_CANCEL y ACTION_UP en MotionEvent?
- Detección de vistas invisibles en un evento de movimiento
También he puesto un punto de quiebre en la problemática ACTION_CANCEL pero no soy capaz de reconocer nada en el MotionEvent que pueda representar "B".
- Event.getAction () nunca utiliza MotionEvent.ACTION_UP
- No hay interrupción en SwipeRefreshLayout.java en el módulo android 5 onInterceptTouchEvent
- Android: Recyclerview horizontal dentro de una Recyclerview vertical
- ¿Qué causa un MotionEvent.ACTION_CANCEL en Android?
- Pase el evento de movimiento a la Scrollview primaria cuando Listview en la parte superior / inferior
- Combinación WindowManager.LayoutParams que puede pasar eventos a capas bajo TYPE_SYSTEM_ALERT o smilar
- Soporte para Gamepad Android
- Android inyecta evento táctil
Si un padre está interceptando el evento de movimiento, la única manera de evitarlo es evitar que el padre intercepte ese evento. Esto se puede manejar bien de dos maneras.
Sin ver código específico y querer una solución generalizada sugeriría lo siguiente.
Yo sugeriría manejar sus eventos de contacto para los padres y el niño manejando el
RequestDisallowInterceptTouchEvent (booleano) y
OnInterceptTouchEvent (android.view.MotionEvent) de cada vista / viewgroup dentro de las vistas afectadas A, B C.
Al deshabilitar intercepciones de padres en el niño, esto le ayuda a interceptar a los padres que no ha tenido en cuenta, y también a personalizar y variar los elementos secundarios de un padre.
Esto debe ser administrado desde el padre más alto de su grupo view / viewGroup y administrado a través de todas las relaciones entre padres e hijos.
Comprobando las vistas de lista, cualquier elemento que tenga un evento táctil incorporado.
Android.com/training/gestures/viewgroup
En cuanto a encontrar la visión ofensiva que está interceptando el evento, eso no puede ser contestado excepto por la lógica de:
Ir a través de cada padre a niño / padre a niño vista. Compruebe metodológicamente el manejo de la unidad en cada grupo de vista / vista como se muestra en mi diagrama.
Aquí hay más detalle en estas respuestas:
https://stackoverflow.com/a/30966413/3956566
https://stackoverflow.com/a/6384443/3956566
Estoy seguro de que entiende esto, pero para mí, es la solución más simple.
Más allá de esto, tendríamos que mirar su código para solucionarlo.
Si tengo tu pregunta correcta, estás recibiendo ACTION_CANCEL
probablemente en el padre y necesitas encontrar esa vista. Dado el evento X e Y, puede encontrar la vista que contiene estas coordenadas en el primer momento ACTION_CANCEL
ocurrió. Trate de llamar a este método ya sea con el principal padre (android.R.id.content) o el ViewGroup
que está tratando.
private View findViewAt(View contentView, int eventX, int eventY) { ArrayList<View> unvisited = new ArrayList<View>(); unvisited.add(contentView); while (!unvisited.isEmpty()) { View child = unvisited.remove(0); if(isViewContains(child, eventX, eventY) { Log.i(TAG, "view found! "); unvisited.clear(); return child; } if (!(child instanceof ViewGroup)){ continue; } ViewGroup group = (ViewGroup) child; final int childCount = group.getChildCount(); for (int i=0; i< childCount; i++){ unvisited.add(group.getChildAt(i)); } } return null; } private boolean isViewContains(View view, int eventX, int eventY) { int[] location = new int[2]; view.getLocationOnScreen(location); int x = location[0]; int y = location[1]; int width = view.getWidth(); int height = view.getHeight(); return eventX < x || eventX > x + width || eventY < y || eventY > y + height; }
En mi experiencia, un caso que hace que una vista reciba un evento ACTION_CANCEL es después de que A es tocado por los usuarios y arrastra su dedo fuera del área de A, Si se enfrenta a este caso, agregue un método para comprobar la ubicación en dispatchTouchEvent () ayuda.
- Android Studio – tarea de gradle para ejecutar después de SYNC
- Android InputStream que deja caer dos primeros bytes (BluetoothChat modificado)