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.

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?

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); 
  • El cajón de navegación no funciona cuando startActivity se utiliza en el primer caso de selectItem
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.