Android ViewPager, использующий SubsamplingScaleImageView, иногда отображает пустой экран при скольжении изображений

Я сделал ViewPager используя SubsamplingScaleImageView от davemorrissey

При скольжении ViewPager следующий слайд будет пустым в течение нескольких секунд до загрузки изображения.

Кто-нибудь сталкивался с такой же проблемой? Любые указатели на возможные исправления?

viewPager = (ViewPager) findViewById(R.id.pager);
magePagerAdapter adapter = new ImagePagerAdapter();       
viewPager.setAdapter(adapter);

ArrayList<String> imageFull = new ArrayList<String>();
for(int i=0;i<10;i++){
String image = "mnt/sdcard/imageDemo"+i+".jpg";
imageFull.add(image);
}


    @Override
    public Object instantiateItem(ViewGroup container, int position) {
      Context context = ImageGallery.this;

      SubsamplingScaleImageView fullImage = new SubsamplingScaleImageView(ImageGallery.this);
      fullImage.setImage(ImageSource.uri(imageFull.get(position)));         

      return fullImage;
   }


   @Override
   public void destroyItem(ViewGroup container, int position, Object object) {
      ((ViewPager) container).removeView((SubsamplingScaleImageView) object);

   }

2 ответа

Решение

Я смог обойти это с этим патчем. Я также написал аналогичный ответ в проблеме проблемы видимости

initialiseBaseLayer называется первым onDraw поэтому он не загружается до тех пор, пока страница не станет частично видимой.

Проблема в том, что инициализация снаружи onDraw вы теряете доступ к холсту, который используется для расчета максимальных размеров растрового изображения:

private Point getMaxBitmapDimensions(Canvas canvas) {
    if (VERSION.SDK_INT >= 14) {
        try {
            int maxWidth = (Integer)Canvas.class.getMethod("getMaximumBitmapWidth").invoke(canvas);
            int maxHeight = (Integer)Canvas.class.getMethod("getMaximumBitmapHeight").invoke(canvas);
            return new Point(maxWidth, maxHeight);
        } catch (Exception e) {
            // Return default
        }
    }
    return new Point(2048, 2048);
}

Таким образом, вам придется предоставить максимальные размеры самостоятельно. Я использую эту функцию. Я сохраняю значение во время onCreate действия, а затем ViewPager получить это значение.

Перед установкой вызова изображения fullImage.setMaxDimensions(x, y) и это все.

Он отлично работает (в моем случае) для ViewPager, но не для RecyclerView, поэтому используйте его с осторожностью.

Ваш экран черный, потому что изображение еще не декодировано.

Ты можешь использовать:

public final void setImage(ImageSource imageSource, ImageSource previewSource)

и использовать эскиз в качестве предварительного просмотра. Предварительный просмотр отображается до завершения декодирования изображения.

Обратите внимание, что:

Предварительный просмотр нельзя использовать, если для основного изображения не указаны размеры.

Не проверено, но что-то вроде:

Uri uri = imageFull.get(position);
Bitmap preview = MediaStore.Images.Thumbnails.getThumbnail(
                             getContentResolver(), uri,
                             MediaStore.Images.Thumbnails.MINI_KIND,
                             null);

ImageSource src = ImageSource.uri(uri);
src .dimensions(w, h); // if you don't know the size, you can just decode the bounds of your image which is quite fast

fullImage.setImage(src , ImageSource.bitmap(preview));  

Если генерация миниатюр замедляется для вас, не стесняйтесь делать это в AsyncTask.

Другие вопросы по тегам