如何延迟毕加索图像加载



我在MainActivity(GridView)和DetailActivity之间实现了共享元素活动过渡动画。单击项目时,网格项中的图像将放大成为详细信息活动中的背景图像。我通过将 MainActivity 上的图像保存到文件中,然后在通过毕加索下载更高质量的图像之前将其用作 DetailActivity 中的占位符图像,从而使过渡非常顺利。当毕加索完成任务时,更高质量的图像将非常整齐地替换占位符。

来自 onCreateView() in DetailActivityFragment 的代码.java

ImageView iv = (ImageView) mRootview.findViewById(R.id.movie_poster);
try {
    // Prepare "InterimPoster" jpeg file to be placeholder image
    Bitmap bitmap = BitmapFactory.decodeStream(c.openFileInput("InterimPoster"));
    Picasso.with(c).load("http://image.tmdb.org/t/p/w780" + mMovieInfo[2])
            .placeholder(new BitmapDrawable(getResources(), bitmap))
            .fit()
            .centerCrop()
            .noFade()
            .into(iv);
} catch (FileNotFoundException e) {
    e.printStackTrace();
}

至于动画,我像这里的链接步骤1-3一样实现它 https://guides.codepath.com/android/Shared-Element-Activity-Transition

但是,在过渡动画完成之前,当更高质量的图像完成下载时,有时会闪烁。移动时,放大的图像将被新图像替换,这是一个令人不快的动画。

所以我想知道如何解决这种闪烁?我能想到的一件事是延迟图像下载,因为我已经有较低质量的图像作为占位符。我该怎么做?

这里是视频。通常,在我的测试设备上,它有80%的时间是平滑的,但幸运的是,在这个视频中,它大部分时间都在闪烁。

什么是

动画? 在动画结束时加载图像

 TranslateAnimation translateAnimation = new TranslateAnimation(0,1.5f,0,1.5f);
    translateAnimation.setAnimationListener(new Animation.AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {
        }
        @Override
        public void onAnimationEnd(Animation animation) {
               //load image when animation end
        }
        @Override
        public void onAnimationRepeat(Animation animation) {
        }
    });

  LayoutTransition.TransitionListener transitionListener = new LayoutTransition.TransitionListener() {
        @Override
        public void startTransition(LayoutTransition transition, ViewGroup container, View view, int transitionType) {
        }
        @Override
        public void endTransition(LayoutTransition transition, ViewGroup container, View view, int transitionType) {
                    //load image when animation end
        }
    };

现在我找到了一种延迟毕加索图像加载(或任何其他任务)的方法。使用Handler和Runnable非常简单。

现在我的代码看起来像这样。现在无论如何,图像替换都非常顺利。

    // Set Background Poster in Try-catch in case file cannot be open
    try {
        // Get/Prepare "InterimPoster" jpeg file to be placeholder image
        final ImageView iv = (ImageView) mRootview.findViewById(R.id.movie_poster);
        final Bitmap bitmap = BitmapFactory.decodeStream(c.openFileInput("InterimPoster"));
        final Drawable lowResPoster = new BitmapDrawable(getResources(), bitmap);
        iv.setImageDrawable(lowResPoster);
        // Download higher resolution image with 0.8 sec delay to avoid load complete before
        // animation finishes (causing some flicker/overflow image problem).
        Handler handler = new Handler();
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                Picasso.with(c).load("http://image.tmdb.org/t/p/w780" + mMovieInfo[2])
                        // still need placeholder here otherwise will flash of white image
                        .placeholder(lowResPoster)
                        .error(lowResPoster)
                        .fit()
                        .centerCrop()
                        .noFade() // without this image replacement will not be smooth
                        .into(iv);
            }
        };
        handler.postDelayed(runnable, 800);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }

尝试以下代码:

首先通常使用毕加索将占位符加载到图像视图中

iv.setImageBitmap(bitmap);

然后像这样使用 SharedElement Listener

Transition sharedElementEnterTransition = getWindow().getSharedElementEnterTransition();sharedElementEnterTransition.addListener(new TransitionListenerAdapter() {
     @Override
      public void onTransitionEnd(android.support.transition.Transition transition) {
                super.onTransitionEnd(transition);
         Picasso.with(c).load("http://image.tmdb.org/t/p/w780" + mMovieInfo[2])
        .placeholder(new BitmapDrawable(getResources(), bitmap))
        .fit()
        .centerCrop()
        .noFade()
        .into(iv);
       }
  });

要延迟某些进程,可以使用 Handler()。

例。

new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            // write your codes here.. this  will delay 2 seconds...
           startActivity(new Intent(this,MySecondActivity.class); 

        }
    },2000);

最新更新