2015-11-26 13 views
5

Odtwarzam wiele obrazów sekwencyjnie na tym samym SimpleDraweeView. Problem polega na tym, że po przesłaniu nowego żądania imageURI, SimpleDrweeView usunie bieżący wyświetlany obraz i zastąpi go nic, dopóki nie zostanie pobrany URI. Więc pozostawi luki w sekwencji gry (możesz pomyśleć o tym, co próbuję zrobić, to animacja animowana z wykorzystaniem lokalnych zdjęć). To, co chciałbym, aby SimpleDrweeView pozostawił bieżący obraz, dopóki nie zostanie pobrany nowy, a następnie po prostu go zamieni, kiedy będzie gotowy.Fresco: Użyj bieżącego obrazu wyświetlonego w Drawie jako symbolu zastępczego dla następnego żądania.

Próbowałem użyć schematu o niskiej rozdzielczości/wysokiej rozdzielczości z biletu this, aby umieścić stare uri jako symbol zastępczy, ale to nie zadziałało (miało taki sam efekt jak poprzednio).

To co mam teraz:

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

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

A to, co starałem tak daleko (nie działa):

   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); 

Odpowiedz

3

Jestem częścią zespołu i może być Fresco w stanie pomóc. To dziwne, że doświadczasz tego samego problemu z kombinacją niskiej rozdzielczości/wysokiej rozdzielczości. Jeśli obraz jest aktualnie wyświetlany, oznacza to, że powinien znajdować się w pamięci podręcznej obrazów bitmapowych, co z kolei oznacza, że ​​powinien być w stanie załadować natychmiast, gdy zostanie ustawiony jako obraz o niskiej rozdzielczości, gdy następnym razem przejdziesz do następnej klatki. Czy jesteś pewien, że ustawiasz prawidłowy uri jako obraz o niskiej rozdzielczości? (Uri) draweeView.getTag() wygląda na podejrzanego. Sprawdziłbym podwójnie tę część.

Jeśli uri jest rzeczywiście poprawne, ale obraz nie znajduje się już w pamięci podręcznej bitmapy, warto byłoby zbadać, dlaczego obraz, który jest widoczny, nie jest już buforowany, ponieważ mamy jawną logikę, która powinna zapobiegać wyświetlaniu widocznemu obrazy. Zobacz, jak śledzić to za pomocą szczegółowego rejestrowania here.

Jeśli wszystkie powyższe czynności nie przyniosą rezultatu, trzecią opcją jest faktyczne wdrożenie własnego DataSource. Mogę w tym pomóc, ale może to być trochę wciągające. Podstawową ideą jest implementacja DataSource, która owija kolejny DataSource, który faktycznie dostarcza obraz. Następnie możesz zrobić coś takiego:

// 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

Dziękuję bardzo za to. Zamierzam spróbować w przyszłym tygodniu i dam ci znać o wynikach. – Jimmy

+0

@plamenko dlaczego zdecydowałeś się ukryć istniejący obraz po załadowaniu nowego? pod warunkiem, że wybór ukryje lub okaże się znacznie bardziej przydatny. –

+0

@AntonMalyshev, to nie jest tak, że postanowiliśmy ukryć istniejący obraz jako taki. Jest to raczej konsekwencja projektu Szuflady. Rysujący uzyskuje obrazy do wyświetlenia z DataSource (który z kolei pochodzi od Dostawcy ). Szuflada ma tylko jednego dostawcę, co znacznie upraszcza projektowanie, ponieważ logika muxingu jest tam zamknięta zamiast w sterowniku Drawee. Czystym sposobem na osiągnięcie tej funkcjonalności z firmą Drawee jest posiadanie dostawcy, który to robi. – plamenko

Powiązane problemy