【问题标题】:How can load the images with the Glide in ImageSwitcher如何在 ImageSwitcher 中使用 Glide 加载图像
【发布时间】:2016-06-19 07:40:51
【问题描述】:

为了创建图像幻灯片,我想使用带有计时器的图像切换器。 我读了this blog post 很清楚,但它不会从网络加载图像。 现在我想使用 Glide Library 从网络加载图像。

这是 MainActivity :

public class MainActivity extends Activity {
    private ImageSwitcher imageSwitcher;

    private int[] gallery = { http://www.helloworld.com/image1.png, http://www.helloworld.com/image2.png, http://www.helloworld.com/image3.png,
            http://www.helloworld.com/image4.png, };

    private int position;

    private static final Integer DURATION = 2500;

    private Timer timer = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageSwitcher = (ImageSwitcher) findViewById(R.id.imageSwitcher);
        imageSwitcher.setFactory(new ViewFactory() {

            public View makeView() {
                return new ImageView(MainActivity.this);
            }
        });

        // Set animations
        // https://danielme.com/2013/08/18/diseno-android-transiciones-entre-activities/
        Animation fadeIn = AnimationUtils.loadAnimation(this, R.anim.fade_in);
        Animation fadeOut = AnimationUtils.loadAnimation(this, R.anim.fade_out);
        imageSwitcher.setInAnimation(fadeIn);
        imageSwitcher.setOutAnimation(fadeOut);
    }

    // ////////////////////BUTTONS
    /**
     * starts or restarts the slider
     * 
     * @param button
     */
    public void start(View button) {
        if (timer != null) {
            timer.cancel();
        }
        position = 0;
        startSlider();
    }

    public void stop(View button) {
        if (timer != null) {
            timer.cancel();
            timer = null;
        }
    }

    public void startSlider() {
        timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask() {

            public void run() {
                // avoid exception:
                // "Only the original thread that created a view hierarchy can touch its views"
                runOnUiThread(new Runnable() {
                    public void run() {
                        imageSwitcher.setImageResource(gallery[position]);
                        position++;
                        if (position == gallery.length) {
                            position = 0;
                        }
                    }
                });
            }

        }, 0, DURATION);
    }

    // Stops the slider when the Activity is going into the background
    @Override
    protected void onPause() {
        super.onPause();
        if (timer != null) {
            timer.cancel();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (timer != null) {
            startSlider();
        }

    }

}

我尝试使用 glide 加载图像,但我不知道该怎么做。

【问题讨论】:

    标签: android android-widget android-glide imageswitcher


    【解决方案1】:

    这很容易做到,您只需使用Glide 将图像加载到ImageView,您可以通过imageSwitcher.getCurrentView() 方法从ImageSwitcher 获取该图像。因此,您需要将runOnUiThread 方法的run 中的代码替换为下一个代码:

    Glide.with(MainActivity.this)
        .load(gallery[position])
        .asBitmap()
        .listener(new RequestListener<String, Bitmap>() {
            @Override
            public boolean onException(Exception e, String model, Target<Bitmap> target, boolean isFirstResource) {
                return false;
            }
    
            @Override
            public boolean onResourceReady(Bitmap resource, String model, Target<Bitmap> target, boolean isFromMemoryCache, boolean isFirstResource) {
                position++;
                if (position == gallery.length) {
                    position = 0;
                }
                imageSwitcher.setImageDrawable(new BitmapDrawable(getResources(), resource));
                return true;
            }
        }).into((ImageView) imageSwitcher.getCurrentView());
    

    也不要忘记用适当的网址替换您的图片网址(您现在有一些我看到的虚拟网址)。所以你的gallery 数组应该是String[] 数组。

    不要忘记在您的AndroidManifest.xml 中添加android.permission.INTERNET

    最后,您需要在 xml 中将 ImageSwitcherandroid:layout_width 属性更改为 match_parent,否则 Glide 不会在其中加载图像。

    【讨论】:

      【解决方案2】:

      我认为批准的答案很棒,但缺少一些关键。 当他们更新当前图像时,这基本上只是替换了视图中的图像。这意味着我们可能根本不使用 ImageSwitcher。我们需要做的是更新下一个视图然后显示它。这将使我们还可以看到我们添加的任何过渡效果。

      我已经在我自己的代码中分离出所有这些逻辑以使其干净,但这里它是 RAW 格式。

      设置 ImageSwitcher

         
      
          Animation in = AnimationUtils.loadAnimation(this,android.R.anim.fade_in);
             Animation out = AnimationUtils.loadAnimation(this,android.R.anim.fade_out);
             imageSwitcher.setFactory(() -> {
                      ImageView imageView = new ImageView(getApplicationContext());
                      imageView.setLayoutParams(new FrameLayout.LayoutParams(
                              FrameLayout.LayoutParams.MATCH_PARENT,
                              FrameLayout.LayoutParams.MATCH_PARENT
                      ));
                      return imageView;
                  });
             imageSwitcher.setInAnimation(in);
             imageSwitcher.setOutAnimation(out);
      
        
      
      

      调用它来更新下一张图片

         
      
          RequestOptions requestOptions = new 
             RequestOptions().diskCacheStrategy(DiskCacheStrategy.ALL);
             Bitmap nextImage = getAppropriateImage();
             GlideApp.with(this)
                .load(nextImage)
                .apply(requestOptions)
                .into((ImageView) imageSwitcher.getNextView());
             imageSwitcher.showNext();
      
      

      【讨论】:

      • 2 cmets 来改进这个答案:1) 在加载“下一个”图像之前不要调用 showNext() 2) 将“下一个”视图设置为 INVISIBLE,就像下面的回复建议的那样
      【解决方案3】:

      我使用了@rom4ek 的版本,但我遇到了一些崩溃:

      致命异常:java.lang.RuntimeException 画布:尝试使用回收的位图 android.graphics.Bitmap@7ad49c4

      我认为这是因为drawable 未设置为传递给into(...) 的相同ImageView

      我将其更改为使用“下一个视图”。我们必须将 Glide 的可见性从 GONE 设置为 INVISIBLE

      imageSwitcher.getNextView().setVisibility(View.INVISIBLE);
      Glide.with(...)
          .load(url)
          .listener(new RequestListener<String, Bitmap>() {
              @Override
              public boolean onException(Exception e, String model, Target<Drawable> target, boolean isFirstResource) {
                  return false;
              }
      
              @Override
              public boolean onResourceReady(Drawable resource, String model, Target<Drawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
                  imageSwitcher.setImageDrawable(resource);
                  return true;
              }
          }).into((ImageView) imageSwitcher.getNextView());
      

      Kotlin 版本:

      it.nextView.visibility = View.INVISIBLE
      Glide.with(...)
          .load(url)
          .listener(object : RequestListener<Drawable> {
              override fun onLoadFailed(
                  e: GlideException?,
                  model: Any?,
                  target: Target<Drawable>?,
                  isFirstResource: Boolean
              ): Boolean {
                  return false
              }
      
              override fun onResourceReady(
                  resource: Drawable?,
                  model: Any?,
                  target: Target<Drawable>?,
                  dataSource: DataSource?,
                  isFirstResource: Boolean
              ): Boolean {
                  it.setImageDrawable(resource)
                  return true
              }
          })
          .into(it.nextView as ImageView)
      

      【讨论】:

      • >> 我将其更改为使用“下一个视图”。我们必须将 Glide 的可见性从 GONE 设置为 INVISIBLE。这对我有用,因为我最初在 Glide 将图像加载到“下一个”视图时遇到问题。我怀疑这是因为该视图不可见,而 Glide 只是跳过了它
      猜你喜欢
      • 1970-01-01
      • 2016-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-01
      • 1970-01-01
      • 2021-08-17
      相关资源
      最近更新 更多