Necesito ayuda con respecto a un problema muy extraño. Parece que soy el único que se topó con él. En mi aplicación, ni requestLayout() ni invalidate() tienen ningún efecto dentro de un fragmento anidado en dispositivos que ejecutan Android 4.0, 4.1 y 4.2 (probado tanto en emuladores como en dispositivos reales).

Cuando navego a donde tengo que llamar a requestLayout(), la jerarquía de diseño de la actividad contiene un flujo de detalles maestros y se ve más o menos así (tenga en cuenta que agrego todos los fragmentos dinámicamente a un contenedor FrameLayout):

<DrawerLayout>
  <CoordinatorLayout>
    <LinearLayout (horizontal)>
      <fragment in FrameLayout --> master/>
        <ViewPager (using FragmentStatePagerAdapter)>
          <PagerTabStrip/>
          <fragment pages, each being only a single RecyclerView/>
        </ViewPager>
      </fragment in FrameLayout>
      <fragment in FrameLayout --> detail>
        <RelativeLayout>
          <ViewPager (using FragmentStatePagerAdapter)/>
          <a custom footer view that can be expanded to fill the screen/>
        </RelativeLayout>
      </fragment in FrameLayout>
    </LinearLayout>
    <AppBarLayout>
      <Toolbar>
    </AppBarLayout>
  </CoordinatorLayout>
  <NavigationView/>
</DrawerLayout>

Ahora, un problema que tuve fue que el pie de página comenzó oculto debido al comportamiento de CoordinatorLayout. El problema se describe aquí con más detalle.

Dado que mi pie de página se puede expandir para llenar la pantalla, tuve que implementar una solución personalizada:

  1. Para asegurarme de que el pie de página no comience oculto, agrego la altura de la barra de herramientas como margen inferior a la vista del fragmento de detalle.
  2. Para evitar que el pie de página se desplace, registro un OnOffsetChangedListener en AppBarLayout y paso los cambios de compensación al fragmento de detalle, que a su vez los pasa a su vista raíz y llama a requestLayout() en él.
  3. Dentro de onMeasure(), la vista raíz agrega el desplazamiento a la altura medida originalmente.

En Android 4.3 y superior, esto funciona perfectamente. El pie de página siempre está anclado en la parte inferior de la pantalla y. Cuando se expande, la vista también se fija en la parte superior al crecer y reducirse según el desplazamiento de la barra de la aplicación. No hay problemas.

Pero debajo de Android 4.3, después de un tiempo, requestLayout() simplemente no tiene ningún efecto. Probé invalidate() y forceLayout() también. No se llama a onMeasure() ni a onLayout() y la barra sigue desplazándose, a veces flotando sobre la parte inferior de la pantalla y otras veces desplazándose fuera de la pantalla. No tengo ni idea de cómo es posible, pero observé que depende de los ViewPagers: al deslizar cualquiera de ellos como máximo dos veces, el pie de página se separa de alguna manera.

Por ahora, puse algunas cláusulas if para asegurarme de que mi implementación solo se active para 4.3 y superior. Entonces, en Android 4.0, 4.1 y 4.2, el pie de página se desplaza hacia adentro y hacia afuera. Pero eso apesta, así que por favor ayuda: ¿Qué puedo hacer para que funcione para esas versiones? Alternativamente, ¿tiene otras ideas sobre cómo fijar el pie de página en la parte inferior y aún así hacer que se vea bien?

respuesta

Resolví esto moviendo el pie de página hacia el coordinador y usando un BottomSheet . Esto asegura que siempre esté en el lugar correcto.