Cambiar la forma en que SlidingDrawer responde al trackball o al cursor
(Tenga en cuenta que el comportamiento descrito en esta pregunta sólo apareció debido a algo aparentemente no relacionado con lo que estábamos haciendo.
Tenemos una actividad de Android con un GridView
y un SlidingDrawer
dentro de un RelativeLayout
. La forma en que esta actividad responde a la trackball (o teclas de cursor) es bastante extraña. El foco se moverá entre los elementos en el GridView, pero cada vez que el cursor se mueve en una dirección "fuera" de la GridView. (Por ejemplo, cuando está en la parte superior, izquierda cuando ya está en el elemento más a la izquierda) el cajón deslizante se abre o se cierra. En particular, el enfoque se mantiene en el mismo elemento en el GridView — no se mueve al cajón deslizante.
- SlidingPaneLayout.setShadowResource Android
- ¿El mismo SlidingDrawer en todas las actividades?
- ¿Cómo se puede animar un SlidingDrawer?
- Android: SlidingDrawer desaparece bajo SurfaceView
- La vista de desplazamiento no se desplaza dentro del cajón deslizante
Con un trackball esto es particularmente horrible, ya que girar el trackball más allá de su destino real hará que el cajón deslizante se abra y cierre repetidamente.
Hemos determinado que podemos apagar el trackball enteramente reemplazando onTrackballEvent()
. Preferimos que el trackball y el cursor funcionen normalmente en el GridView pero no causen que el cajón corredizo se abra o cierre. En principio, también nos gustaría que la bola de seguimiento se centra en los distintos contenidos del cajón deslizante cuando está abierto.
¿Cómo?
- El cajón corredizo parece semicircular
- Android SlidingDrawer no deshabilita los botones 'debajo' del cajón
- Reducción de la velocidad del cajón deslizante
- Porcentaje abierto de SlidingDrawer en Android
- LinearLayout @ 422725b0 no es un cajón deslizante
- Android ¿Es posible tener múltiples SlidingDrawer
- Color de fondo del cajón deslizante
- Android Drawer Layout no puede encontrar R.layout.drawer_list
Usted puede considerar la creación de vistas personalizadas que amplían GridView
y SlidingDrawer
y el uso de implementaciones personalizadas de onInterceptTouchEvent
y onTouchEvent
para el GridView
y una implementación personalizada sólo para onInterceptTouchEvent
para el SlidingDrawer
. Es posible que no necesite implementar un SlidingDrawer
personalizado dependiendo de qué interacciones de usuario se pueden activar en el handle
Para su GridView
personalizado, darle un interfaz tal vez definido como este:
public interface MyGridViewListener { public boolean shouldPreventScroll(); }
SlidingDrawer
si su SlidingDrawer
personalizado se abre. Este valor devuelto se utilizará para determinar si se deben realizar acciones (para los métodos onInterceptTouchEvent
y onTouchEvent
) en el GridView
. Así que cuando se abre el SlidingDrawer
, las acciones realizadas en el GridView
no activarán nada en el SlidingDrawer
.
Actividad:
MyGridView gridView = (MyGridView) findViewById(R.id.gridView); gridView.setMyGridViewListener(new MyGridViewListener() { @Override public boolean shouldPreventScroll() { return slidingDrawer.isOpened(); } });
MyCustomGridView: shouldIntercept
será llamado cada vez que ocurra algún evento de touch / track en el GridView
.
private boolean shouldIntercept() { boolean shouldIntercept = false; if(myGridViewListener != null) { shouldIntercept = myGridViewListener.shouldPreventScroll(); } return shouldIntercept; } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return shouldIntercept() ? true : super.onInterceptTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent ev) { return shouldIntercept() ? true : super.onTouchEvent(ev); } @Override public boolean onTrackballEvent(MotionEvent event) { return shouldIntercept() ? true : super.onTrackballEvent(event); } public MyGridViewListener getMyGridViewListener() { return myGridViewListener; } public void setMyGridViewListener( MyGridViewListener myGridViewListener) { this.myGridViewListener = myGridViewListener; }
Espero que esto le señale en una dirección correcta o por lo menos ayuda
Mientras jugaba con un cajón deslizante personalizado establecí el diseño de la manija a algún valor extraño, algo así como
handle.layout(0, 0,0, 0);
Para hacer desaparecer el mango, pero arrastrando un dedo desde el lateral de la pantalla todavía abriría el cajón deslizante, que es lo que no quería, así que me puse
handle.layout(10000, 10000, 10000, 10000);
Que se movió fuera del área visible y el cajón ya no se podía sacar manualmente arrastrando desde el lado de la pantalla. Después de mirar el código fuente su posición del asa que determina el deslizamiento del cajón, deshacerse de la manija y debe resolver su problema.
Si necesita abrir / cerrar la llamada del cajón animateOpen () / animateClose ()
Como resultó, causamos este problema por un poco relacionado de tonterías. Queríamos que la tecla MENU abra y cierre el SlidingDrawer
. Hicimos esto al sobreponer onPrepareOptionsMenu()
:
public boolean onPrepareOptionsMenu (Menu menu) { slidingDrawer.animateToggle(); return true; }
Esto funciona bien; Pero resulta que se puede llamar cuando el menú no está a punto de abrirse. En particular, si la Activity
utiliza setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT)
, entonces un evento de clave no controlada terminará accediendo al menú. Esto incluye el movimiento del trackball fuera del borde de la pantalla.
La manera menos tonta de obtener el comportamiento deseado es
public boolean onKeyUp(int keyCode, KeyEvent event) { if(keyCode==KeyEvent.KEYCODE_MENU) { slidingDrawer.animateToggle(); } return super.onKeyUp(keyCode,event); }
Mientras tanto, podemos conseguir que el trackball se mueva dentro del SlidingDrawer
cuando está abierto configurando un SlidingDrawer.OnDrawerOpenListener
que llama
slidingDrawer.getContent().requestFocus();
Finalmente parece una buena idea llamar
slidingDrawer.getHandle().setFocusable(false);
- Solo se pueden usar 16 bits inferiores para requestCode (Google play services)
- Problemas de Android Soundpool