Análisis del código fuente del principio de enfoque de Android TV
Creo que muchos desarrolladores que son nuevos en el desarrollo de Android TV se verán torturados por varios problemas de enfoque. Ya sea que estemos aprendiendo tecnología u otros conocimientos, necesitamos aprender y comprender los principios para poder abordar con calma los problemas cuando los encontremos. Analicemos el proceso de distribución de enfoque de Android.
La distribución de eventos de enfoque de Android comienza desde ProcessKeyEvent de ViewRootImpl. El código fuente es el siguiente:
El código fuente es relativamente largo. Explicaré lentamente los detalles específicos a continuación.
El método despachoKeyEvent devuelve verdadero, lo que indica que el evento de enfoque se ha consumido.
El código fuente del método despachoKeyEvent() de ViewGroup es el siguiente:
(2) El flujo de ejecución del método despachoKeyEvent de ViewGroup
(3) Lo siguiente es el código fuente DispatchKeyEvent de la vista del método
Me sorprendió descubrir que se ejecutó el método onKey en onKeyListener. Si el método onKey devuelve verdadero, entonces el método DispatchKeyEvent también devolverá verdadero. p> Podemos sacar esta conclusión: si tiene un viewGroup que no pertenece al evento clave, puede usar el método onKey en viewGroup para enviar un KeyEvent al viewGroup. strong> Puede concluir que si desea modificar la distribución de los eventos de enfoque de ViewGroup, puede hacer esto:
NOTA: En la práctica, es teóricamente posible interceptar agregando un oyente al método DispatchKeyEvent. enfocar los temas, controlándolos así.
(1) Después de que el método despachoKeyEvent devuelve falso, primero obtendrá el valor de dirección de la clave, que es un parámetro de tipo int. Este valor de dirección se utilizará más adelante para la búsqueda de enfoque.
(2) Luego llame al método findFocus() de DecorView para encontrar la subvista enfocada capa por capa: el método isFocused() determina si la vista ha obtenido el enfoque (mPrivateFlags y PFLAG_FOCUSED) ! = 0 Igual que el método isFocused() de la vista.
El método isFocused() es para determinar si la vista ha obtenido el foco. Si viewGroup ha obtenido el foco, regresa a sí mismo; de lo contrario, encuentra el foco a través del método mFocused findFocus(). mFocused es en realidad la subvista del ViewGroup que tiene el foco, y si mView no es una subvista del ViewGroup, entonces mView no es una subvista del ViewGroup. mFocused es en realidad una subvista del ViewGroup que recibe el foco.
(3) Regrese al método ProcessKeyEvent. Si el método findFocus devuelve que mFocused no está vacío, es decir, busca la vista actualmente enfocada (mFocused), entonces focusSearch cambiará la dirección (el botón del control remoto está). presionado) como parámetro, entonces focusSearch tomará la dirección (la dirección en la que se presionó el botón del control remoto) como parámetro y encontrará la siguiente vista que se enfocará en esa dirección específica, entonces, si esa vista no lo está. vacío, deja que esa vista se enfoque.
(4) Implementación del método focusSearch.
El código fuente del método focusSearch es el siguiente:
Puede ver que focusSearch en realidad llama al método focusSearch de la vista principal en línea capa por capa hasta que la vista actual sea la raíz. diseño (método isRootNamespace()), esto se puede ver a través de comentarios. Y FocusFinder encontrará la vista de enfoque encontrada por el método focusSearch de DecorView.
(5) ¿Qué es FocusFinder?
Es una clase que implementa un algoritmo que puede encontrar la siguiente vista enfocada basándose en la vista actualmente enfocada según la dirección clave dada. Si el foco no se intercepta, la clase FocusFinder implementa finalmente la búsqueda de foco del marco de Android.
(6) FocusFinder Cómo encontrar el foco mediante el método findNextFocus.
Así es como la clase FocusFinder encuentra el foco a través de findNextFocus. Cada vez que se ejecuta una capa, se ejecuta el método findNextUserSpecifiedFocus (), que ejecutará el método findUserSetNextFocus del foco (es decir, la Vista actualmente enfocada si la Vista devuelta por este método no es nula y isFocusable = true &). isInTouchMode() = true, entonces el foco encontrado por FocusFinder es la Vista devuelta por findNextUserSpecifiedFocus().
(7) findNextFocus determinará la prioridad de enfoque en función del siguiente ID de vista enfocado establecido en XML.
Podemos sacar las siguientes conclusiones:
1. Si una vista se establece en focusable = true focusable = true focusable = true focusable = false en el diseño XML, entonces Habilidad para encontrar la siguiente vista que se enfoca. Establezca focusable = true & isInTouchMode = true, luego la vista se enfocará primero.
2. El siguiente foco de Vista se puede controlar configurando los valores nextFocusLeft, nextFocusRight, nextFocusUp y nextFocusDown.
Esto es todo en cuanto a la implementación del principio de enfoque de Android. Resumen:
Para facilitar el estudio de los camaradas, he hecho un mapa aquí para facilitar la comprensión de todos ~