2015-11-26 1 views
5

Я воспроизвожу несколько изображений последовательно на одном и том же SimpleDraweeView, проблема в том, что при отправке нового запроса изображенияURI SimpleDrweeView удалит текущее отображаемое изображение и заменит его на ничего, пока URI не будет загружен. Таким образом, он оставит пробелы в последовательности воспроизведения (вы могли бы подумать, что я пытаюсь сделать, это мультяшная анимация с использованием местных фотографий). Что бы я хотел, чтобы SimpleDrweeView оставил текущее изображение до тех пор, пока новый не будет загружен, а затем просто поменяйте его, когда он будет готов.Fresco: Использовать текущее изображение, отображаемое в Drawee, в качестве заполнителя для следующего запроса

Я пробовал использовать схему с низким разрешением/высоким разрешением от this билет, чтобы поместить старый uri в качестве заполнителя, но это не сработало (имело такой же эффект, как и раньше).

Это то, что я сейчас:

SimpleDraweeView draweeView = (SimpleDraweeView) findViewById(R.id.my_image_view); 

draweeView.setImageURI(uri /* local image */); 

И это то, что я пытался до сих пор (не работает):

   SimpleDraweeView draweeView = (SimpleDraweeView) findViewById(R.id.my_image_view); 

      Uri lowResUri, highResUri; 
      DraweeController controller = Fresco.newDraweeControllerBuilder().setTapToRetryEnabled(true) 
        .setLowResImageRequest(ImageRequest.fromUri((Uri) draweeView.getTag())) /*naive way to test the low/high res feature*/ 
        .setImageRequest(ImageRequest.fromUri(uri)) 
        .setOldController(draweeView.getController()) 
        .build(); 
      draweeView.setTag(uri); 
      draweeView.setController(controller); 

ответ

3

Я часть команды Fresco и может быть способный помочь. Странно, что вы испытываете ту же проблему при сочетании с низким разрешением/высоким разрешением. Если изображение в настоящее время отображается, это значит, что оно должно быть в кэш-памяти растровой памяти, что, в свою очередь, означает, что он должен иметь возможность сразу же загружаться при установке изображения с низким разрешением при следующем переключении на следующий кадр. Вы уверены, что используете правильный uri как изображение с низким разрешением? (Uri) draweeView.getTag() выглядит подозрительно. Я бы дважды проверял эту часть.

Если uri действительно правильный, но изображение больше не находится в кеше растрового изображения, было бы интересно исследовать, почему видимое изображение больше не кэшируется, поскольку у нас есть явная логика, которая должна предотвращать выселение видимых изображений. Посмотрите, как отслеживать это с подробным протоколированием here.

Если все вышеперечисленное не выполнено, третьи варианты - фактически реализовать свой собственный DataSource. Я могу помочь с этим, но это может быть несколько вовлекающим. Основная идея заключается в реализации DataSource, который обертывает другой DataSource, который фактически предоставляет изображение. Тогда вы можете сделать что-то вроде этого:

// keep this instance somewhere 
mMyDataSourceSupplier = new MyDataSourceSupplier(); 

// build controller by specifying your custom datasource supplier instead of specifying any URIs. 
Fresco.newDraweeControllerBuilder() 
    .setDataSourceSupplier(mMyDataSourceSupplier) 
    .build() 

// later, when you need to change the image do 
mMyDataSourceSupplier.setUri(nextUri); 

// this is just an outline 
class MyDataSourceSupplier implements Supplier<DataSource<CloseableReference<CloseableImage>>> { 

    private Uri mCurrentUri; 
    private DataSource<CloseableReference<CloseableImage>> mCurrentDataSource; 

    public void setUri(Uri uri) { 
    mCurrentUri = uri; 
    if (mCurrentDatasource != null) { 
     mCurrentDataSource.setUri(uri); 
    } 
    } 

    @Override 
    public DataSource<CloseableReference<CloseableImage>> get() { 
    mCurrentDataSource = new MyDataSource(); 
    mCurrentDataSource.setUri(uri); 
    return mCurrentDataSource; 
    } 

    private class MyDataSource extends AbstractDataSource<CloseableReference<CloseableImage>> { 
    private DataSource mUnderlyingDataSource; 

    @Override 
    protected void closeResult(@Nullable CloseableReference<CloseableImage> result) { 
     CloseableReference.closeSafely(result); 
    } 

    @Override 
    @Nullable 
    public CloseableReference<CloseableImage> getResult() { 
     return CloseableReference.cloneOrNull(super.getResult()); 
    } 


    @Override 
    public boolean close() { 
     if (mUnderlyingDataSource != null) { 
     mUnderlyingDataSource.close(); 
     mUnderlyingDataSource = null; 
     } 
     return super.close(); 
    } 

    public void setUri(Uri uri) { 
     if (mUnderlyingDataSource != null) { 
     mUnderlyingDataSource.close(); 
     mUnderlyingDataSource = null; 
     } 
     if (uri != null && !isClosed()) { 
     mUnderlyingDataSource = Fresco.getImagePipeline().fetchDecodedImage(ImageRequest.fromUri(uri), null); 
     mUnderlyingDataSource.subscribe(new BaseDataSubscriber { 
      @Override 
      protected void onNewResultImpl(DataSource<List<CloseableReference<CloseableImage>>> dataSource) { 
      MyDataSource.super.setResult(dataSource.getResult(), false); 
      } 
     }); 
     } 
    } 
    } 
} 
+1

Большое спасибо за это. Я собираюсь дать это попробовать на следующей неделе и сообщит вам о результатах. – Jimmy

+0

@plamenko Почему вы решили скрыть существующее изображение при загрузке нового? предоставление выбора скрыть это или нет, кажется, гораздо более полезно. –

+0

@ Антон Малышев, мы не решили скрыть существующее изображение как таковое. Это скорее следствие дизайна чертежа. Drawee получает изображения для отображения из DataSource (который, в свою очередь, поступает от поставщика ). У Drawee есть только один поставщик, который значительно упрощает дизайн, поскольку логика мультиплексирования инкапсулируется там, а не в контроллере Drawee. Чистым способом достижения этой функции с помощью Drawee является наличие поставщика, который это делает. – plamenko

 Смежные вопросы

  • Нет связанных вопросов^_^