Animar Imagen con vista Master-Detail y Glide (Shared Element + Navigation Component) — Parte #2
Esta es la continuación del siguiente post, si aún no lo has visto pasa a darle una leída primero 😁
Previamente vimos como cargar una imagen local y animarla para cuando hay una transición entre el master-detail, ahora lo haremos con Glide! 🙌
Dependencias Requeridas
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.2'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.2'// // Necesario para las transiciones
implementation 'com.google.android.material:material:1.2.1'// Para cargar imagenes
implementation 'com.github.bumptech.glide:glide:4.12.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
- Crearemos dos Fragments como en el post anterior
class FirstFragment : Fragment() { ... }
class SecondFragment : Fragment() { ... }
2. Luego estos dos fragments llevaran un ImageView, cada uno llevara la imagen que queremos mostrar, y agregaremos el atributo mas importante para hacer que funcione el Shared Element: — — — android:transitionName=”sharedElement”
<!-- Este ImageView esta adentro de un ConstraintLayout --><!-- Fragment #1 -->
<ImageView
android:id="@+id/imageView"
android:layout_width="200dp"
android:layout_height="200dp"
android:scaleType="centerCrop"
android:src="@drawable/image"
android:transitionName="sharedElement"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /><!-- Fragment #2 -->
<ImageView
android:id="@+id/imageView"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="centerCrop"
android:src="@drawable/image"
android:transitionName="sharedElement"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
3. Crearemos el archivo que nos ayudara para hacer la animación de la imagen.
4. Los dos ImageView tienen que tener el mismo transitionName y tienen que cargar la misma URL utilizando Glide para que la animación se vea fluida.
Ahora en el Fragment cargaremos el URL, y al hacer click en la imagen enviaremos el URL como argumento para que el Fragment de Detalle lo utilice.
Y en el Fragment de Detalle cargaremos el mismo URL que enviamos como argumento con la llave ARG_IMAGE_URL.
Ahora expliquemos un poco la razón detrás de este listener y otros detalles:
Primero tomemos en cuenta que cargar una imagen de internet siempre toma su tiempo, y este tiempo depende de muchos factores como: el peso de la imagen, velocidad de internet, etc. Por lo mismo se aplica lo siguiente:
- postponeEnterTransition: Llamamos este método porque queremos detener la transición del Fragment y reanudarla hasta que la imagen que estamos cargando con Glide este lista. Tomemos en cuenta que esto provoca que el Fragment se congele y la única forma de descongelarlo es usando: startPostponedEnterTransition() o executePendingTransactions()
- Glide.donAnimate(): Con Glide podemos animar cuando una imagen se coloca en el ImageView, entonces para evitar cualquier tipo de animación como la de un FadeIn por ejemplo, vamos a forzar a que no se anime.
- listener: Aquí viene una de las partes más importantes, porque aquí es donde Glide nos dice: OK, la imagen ya esta lista y disponible para ser cargada en el ImageView. Entonces cuando Glide nos notifica esto, nosotros mandamos a llamar: startPostponedEnterTransition() Que lograra que el Fragment se descongele y la animación de transición se vea fluida.
Si haces las pruebas veras que la animación puede que funcione sin el listener, pero ten en cuenta que no va a funcionar para todos los casos debido a que para algunos usuarios esta imagen cargara lento, por lo tanto agregar el listener es la manera mas segura para lograr que la imagen cargue fluida.
Puedes ver más a detalle el código en el siguiente repositorio 😃