0
votes

Gif n'est pas lu après la transition d'élément partagé. Glide v 4.8.0

Des gifs jouent dans la liste. Mais après la transition des éléments partagés, il s'arrête.

 GlideApp.with(this)
                .load(arguments?.getString(EXTRA_IMAGE_URL))
                .onlyRetrieveFromCache(true)
                .listener(object : RequestListener<Drawable> {
                    override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Drawable>?, isFirstResource: Boolean): Boolean {
                        startPostponedEnterTransition()
                        return false
                    }

                    override fun onResourceReady(resource: Drawable?, model: Any?, target: Target<Drawable>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
                        startPostponedEnterTransition()
                        return false
                    }
                })
                .into(view.ivDialog)
.diskCacheStrategy(DiskCacheStrategy.ALL)


0 commentaires

3 Réponses :


0
votes

Si toutes vos images sont des Gifs, ajoutez simplement .asGif et remplacez votre auditeur par GifDrawable comme ceci,

 private fun setStartPostponedTransition(image: ImageView) {
        image.viewTreeObserver.addOnPreDrawListener(object : ViewTreeObserver.OnPreDrawListener {
            override fun onPreDraw(): Boolean {
                image.viewTreeObserver.removeOnPreDrawListener(this)
                startPostponedEnterTransition()
                return true
            }
        })
    }

Si vos images ne sont pas seulement des Gifs, veuillez vérifier attentivement les 2 solutions ci-dessous

Solution 1-

Assurez-vous que votre activité B est une activité translucide en définissant

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        postponeEnterTransition()

        setContentView(R.layout.activity_main)

         GlideApp.with(context)
        .load(myImageUrl)
        .transition(DrawableTransitionOptions.withCrossFade())
        .listener(object : RequestListener<Drawable> {
            override fun onLoadFailed(
                e: GlideException?,
                model: Any?,
                target: Target<Drawable>?,
                isFirstResource: Boolean
            ): Boolean {
                setStartPostponedTransition(itemImage)
                return false
            }

            override fun onResourceReady(
                resource: Drawable?,
                model: Any?,
                target: Target<Drawable>?,
                dataSource: DataSource?,
                isFirstResource: Boolean
            ): Boolean {
                setStartPostponedTransition(itemImage)
                return false
            }

        })
        .into(itemImage)

}

dans Activity's Theme votre Activity's Theme uniquement et uniquement Si votre activité A est translucide, sinon assurez-vous que vos deux activités ne sont pas translucides ou translucides.

Mise à jour: juin 2020

Solution 2-

Dans votre activité de onCreate() méthode appel postponeEnterTransition() avant de régler votre contenu et appelez le startPostponedEnterTransition() dans les deux de la glisse onLoadFailed() et onResourceReady() les callbacks,

<item name="android:windowIsTranslucent">true</item>

Notez que ce setStartPostponedTransition() est une fonction d'assistance et que nous appelons startPostponedEnterTransition() dans le rappel onPreDraw() de votre ImageView.

GlideApp.with(this)
                .load(arguments?.getString(EXTRA_IMAGE_URL))
                .asGif()
                .onlyRetrieveFromCache(true)
                .listener(object : RequestListener<GifDrawable> {
                    override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<GifDrawable>?, isFirstResource: Boolean): Boolean {
                        startPostponedEnterTransition()
                        return false
                    }

                    override fun onResourceReady(resource: GifDrawable?, model: Any?, target: Target<GifDrawable>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
                        startPostponedEnterTransition()
                        return false
                    }
                })
                .into(view.ivDialog)

Maintenant, vos Gif joueront dans votre ActivityB lors de la transition d' ActivityA une fois que la disposition de votre ImageView sera dessinée à l'écran.

Cette solution est un hack fou! J'espère que cela aidera.

Allez avec la solution 2 et vous êtes prêt à partir!


2 commentaires

Cela ne fonctionne pas dans mon cas. Et que se passe-t-il si seules quelques images sont des Gifs?


@YiyoCastillo J'ai mis à jour la réponse, veuillez la vérifier.



0
votes

Un hack moche qui fonctionne dans mon cas (en Java désolé):

.listener(new RequestListener<Drawable>() {
        @Override
        public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
          return false;
        }

        @Override
        public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
          if (resource instanceof GifDrawable){
            final Handler handler = new Handler();                
            handler.post(() -> resource.setVisible(true, true));
          }
          return false;
        }
      });


0 commentaires

0
votes

Il semble que ce soit un problème de la bibliothèque et nous devrons vivre avec nos propres correctifs personnalisés. Dans mon cas, sans causer de gêne à l'utilisateur, j'ai rechargé le gif avec un délai pour qu'il fonctionne de manière transparente. (De toute façon, l'image sera mise en cache pour la première fois et Glide gère efficacement les appels suivants)

override fun onStop() {
    super.onStop()
    handler?.removeCallbacks(runnable)
}

loadImageIfAvailable est ma propre fonction d'extension pour charger l'image à l'aide de Glide.

fun ImageView.loadImageIfAvailable(url: String?) {
    url?.let {
        Glide.with(context)
            .load(url)
            .into(this)
    }
}


Note: Don't forget to unregister the handlers by calling removeCallbacks on onStop()    
imageView.loadImageIfAvailable(logoUrl)
imageView.transitionName = imageTransitionName
                handler = Handler()
                runnable = Runnable {
                    imageView.loadImageIfAvailable(logoUrl)
                } 
                handler.postDelayed(runnable, 2000)


0 commentaires