Skip to content

Commit 0b41741

Browse files
oprisnikfacebook-github-bot
authored andcommitted
Added RetainingImageSource to simplify replacing a given image on screen
Summary: This adds a new `RetainingImageSource` that can be used to retain the image until the next image source is available. Usage: ``` val retainingImageSource = RetainingImageSource(initialImageSource) // at some point update the image source via: retainingImageSource.updateImageSource(newImageSource); ``` Reviewed By: kartavya-ramnani Differential Revision: D73676558 fbshipit-source-id: a30244138548ff484b9f2e413248c2081981d085
1 parent 36f0d8c commit 0b41741

File tree

4 files changed

+81
-22
lines changed

4 files changed

+81
-22
lines changed

samples/showcase/src/main/java/com/facebook/fresco/samples/showcase/vito/RetainingDataSourceSupplierFragment.java

+8-21
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,12 @@
1414
import android.view.ViewGroup;
1515
import android.widget.ImageView;
1616
import androidx.annotation.Nullable;
17-
import com.facebook.common.references.CloseableReference;
18-
import com.facebook.datasource.RetainingDataSourceSupplier;
19-
import com.facebook.drawee.backends.pipeline.Fresco;
2017
import com.facebook.fresco.samples.showcase.BaseShowcaseFragment;
2118
import com.facebook.fresco.samples.showcase.R;
22-
import com.facebook.fresco.vito.core.impl.source.DataSourceImageSource;
19+
import com.facebook.fresco.vito.core.impl.source.RetainingImageSource;
2320
import com.facebook.fresco.vito.options.ImageOptions;
21+
import com.facebook.fresco.vito.source.ImageSourceProvider;
2422
import com.facebook.fresco.vito.view.VitoView;
25-
import com.facebook.imagepipeline.image.CloseableImage;
26-
import com.facebook.imagepipeline.request.ImageRequest;
2723
import java.util.List;
2824

2925
public class RetainingDataSourceSupplierFragment extends BaseShowcaseFragment {
@@ -51,23 +47,14 @@ public View onCreateView(
5147
@Override
5248
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
5349
final ImageView imageView = view.findViewById(R.id.image_view);
54-
final RetainingDataSourceSupplier<CloseableReference<CloseableImage>> retainingSupplier =
55-
new RetainingDataSourceSupplier<>();
56-
VitoView.show(
57-
new DataSourceImageSource(retainingSupplier), mImageOptions, CALLER_CONTEXT, imageView);
58-
replaceImage(retainingSupplier);
59-
imageView.setOnClickListener(v -> replaceImage(retainingSupplier));
50+
final RetainingImageSource imageSource = new RetainingImageSource();
51+
VitoView.show(imageSource, mImageOptions, CALLER_CONTEXT, imageView);
52+
replaceImage(imageSource);
53+
imageView.setOnClickListener(v -> replaceImage(imageSource));
6054
}
6155

62-
private void replaceImage(
63-
RetainingDataSourceSupplier<CloseableReference<CloseableImage>> retainingSupplier) {
64-
65-
retainingSupplier.replaceSupplier(
66-
Fresco.getImagePipeline()
67-
.getDataSourceSupplier(
68-
ImageRequest.fromUri(getNextUri()),
69-
CALLER_CONTEXT,
70-
ImageRequest.RequestLevel.FULL_FETCH));
56+
private void replaceImage(RetainingImageSource retainingImageSource) {
57+
retainingImageSource.updateImageSource(ImageSourceProvider.forUri(getNextUri()));
7158
}
7259

7360
private synchronized Uri getNextUri() {

vito/core-java-impl/src/main/java/com/facebook/fresco/vito/core/impl/ImageSourceToImagePipelineAdapter.kt

+18
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import com.facebook.fresco.urimod.Dimensions
1818
import com.facebook.fresco.vito.core.ImagePipelineUtils
1919
import com.facebook.fresco.vito.core.impl.source.DataSourceImageSource
2020
import com.facebook.fresco.vito.core.impl.source.ImagePipelineImageSource
21+
import com.facebook.fresco.vito.core.impl.source.RetainingImageSource
2122
import com.facebook.fresco.vito.options.ImageOptions
2223
import com.facebook.fresco.vito.source.EmptyImageSource
2324
import com.facebook.fresco.vito.source.FirstAvailableImageSource
@@ -158,7 +159,24 @@ object ImageSourceToImagePipelineAdapter {
158159
extras,
159160
viewport)))
160161

162+
is RetainingImageSource -> {
163+
imageSource.setImageSourceUpdateFunction { newImageSource ->
164+
createDataSourceSupplier(
165+
newImageSource,
166+
imagePipeline,
167+
imagePipelineUtils,
168+
imageOptions,
169+
callerContext,
170+
requestListener,
171+
uiComponentId,
172+
extras,
173+
viewport)
174+
}
175+
imageSource.dataSourceSupplier
176+
}
177+
161178
is DataSourceImageSource -> imageSource.dataSourceSupplier
179+
162180
else -> NO_REQUEST_SUPPLIER
163181
}
164182
}

vito/core-java-impl/src/main/java/com/facebook/fresco/vito/core/impl/source/DataSourceImageSource.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@ import com.facebook.fresco.vito.source.ImageSource
1414
import com.facebook.imagepipeline.image.CloseableImage
1515

1616
/** ImageSource that directly supplies a DataSource */
17-
class DataSourceImageSource(
17+
open class DataSourceImageSource(
1818
val dataSourceSupplier: Supplier<DataSource<CloseableReference<CloseableImage>>>
1919
) : ImageSource
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
package com.facebook.fresco.vito.core.impl.source
9+
10+
import com.facebook.common.internal.Supplier
11+
import com.facebook.common.references.CloseableReference
12+
import com.facebook.datasource.DataSource
13+
import com.facebook.datasource.RetainingDataSourceSupplier
14+
import com.facebook.fresco.vito.source.ImageSource
15+
import com.facebook.fresco.vito.source.ImageSourceProvider
16+
import com.facebook.imagepipeline.image.CloseableImage
17+
18+
/**
19+
* Retaining image source. This image source allows to be updated to load a new image but retain the
20+
* old image until the new image is available. The image source can be updated by calling
21+
* [updateImageSource].
22+
*/
23+
class RetainingImageSource(
24+
private var currentSource: ImageSource = ImageSourceProvider.emptySource(),
25+
val dataSourceSupplier: RetainingDataSourceSupplier<CloseableReference<CloseableImage>> =
26+
RetainingDataSourceSupplier(),
27+
) : ImageSource {
28+
29+
private var imageSourceUpdateFunction:
30+
((ImageSource) -> Supplier<DataSource<CloseableReference<CloseableImage>>>)? =
31+
null
32+
33+
/**
34+
* Update the image to be displayed. Will keep the current image visible until the new one is
35+
* available.
36+
*
37+
* @param imageSource the new image source to be used
38+
* @param forceReload to force reloading the image, even if the same image source is already set
39+
*/
40+
@JvmOverloads
41+
fun updateImageSource(imageSource: ImageSource, forceReload: Boolean = false) {
42+
if (forceReload || currentSource != imageSource) {
43+
currentSource = imageSource
44+
imageSourceUpdateFunction?.let { dataSourceSupplier.replaceSupplier(it(imageSource)) }
45+
}
46+
}
47+
48+
fun setImageSourceUpdateFunction(
49+
function: (ImageSource) -> Supplier<DataSource<CloseableReference<CloseableImage>>>
50+
) {
51+
imageSourceUpdateFunction = function
52+
updateImageSource(currentSource, true)
53+
}
54+
}

0 commit comments

Comments
 (0)