大图像查看器支持平移和缩放,内存占用极少,提供全面的图像加载选项。由 Subsampling Scale Image View 和 Fresco 提供支持
大图像查看器支持平移和缩放,内存占用极少,提供全面的图像加载选项。由 Subsampling Scale Image View 和 Fresco 提供支持
Big image viewer supporting pan and zoom, with very little memory usage and full featured image loading choices. Powered by Subsampling Scale Image View, Fresco, Glide, and Picasso. Even with gif and webp support!
| pan and zoom | gif support |
|---|---|
Note: please put this download url at the first of your repositories part, otherwise, gradle may search in wrong place.
allprojects {
repositories {
mavenCentral()
}
}
implementation 'com.github.piasy:BigImageViewer:1.8.1'
// load with fresco
implementation 'com.github.piasy:FrescoImageLoader:1.8.1'
// load with glide
implementation 'com.github.piasy:GlideImageLoader:1.8.1'
// progress pie indicator
implementation 'com.github.piasy:ProgressPieIndicator:1.8.1'
// support thumbnail, gif and webp with Fresco
implementation 'com.github.piasy:FrescoImageViewFactory:1.8.1'
// support thumbnail and gif with Glide
implementation 'com.github.piasy:GlideImageViewFactory:1.8.1'
// MUST use app context to avoid memory leak!
// load with fresco
BigImageViewer.initialize(FrescoImageLoader.with(appContext));
// or load with glide
BigImageViewer.initialize(GlideImageLoader.with(appContext));
// or load with glide custom component
BigImageViewer.initialize(GlideCustomImageLoader.with(appContext, CustomComponentModel.class));
Note that if you've already used Fresco in your project, please change
Fresco.initialize into BigImageViewer.initialize.
<com.github.piasy.biv.view.BigImageView
android:id="@+id/mBigImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:failureImage="@drawable/failure_image"
app:failureImageInitScaleType="center"
app:optimizeDisplay="true"
/>
You can disable display optimization using optimizeDisplay attribute, or
BigImageView.setOptimizeDisplay(false), which will disable animation for long
image, and the switch between thumbnail and origin image.
BigImageView bigImageView = (BigImageView) findViewById(R.id.mBigImage);
bigImageView.showImage(Uri.parse(url));
Since 1.5.0, BIV support display animated image, e.g. gif and animated webp, to achieve that,
you need set a custom ImageViewFactory via biv.setImageViewFactory:
// FrescoImageViewFactory is a prebuilt factory, which use Fresco's SimpleDraweeView
// to display animated image, both gif and webp are supported.
biv.setImageViewFactory(new FrescoImageViewFactory());
// GlideImageViewFactory is another prebuilt factory, which use ImageView to display gif,
// animated webp is not supported (although it will be displayed with ImageView,
// but it won't animate).
biv.setImageViewFactory(new GlideImageViewFactory());
Node: if the image is not gif or animated webp, then it will be displayed by SSIV, the image type is not determined by its file extension, but by its file header magic code.
To show a thumbnail before the big image is loaded, you can call below version of showImage:
bigImageView.showImage(Uri.parse(thumbnail), Uri.parse(url));
Note: make sure that you have already called setImageViewFactory.
Since 1.6.0, BIV has experimental support for shared element transition, but it has following known issues:
You can play with the demo app to evaluate the shared element transition support.
bigImageView.setProgressIndicator(new ProgressPieIndicator());
There is one built-in indicator, ProgressPieIndicator, you can implement your
own indicator easily, learn by example.
You can prefetch images in advance, so it could be shown immediately when user want to see it.
BigImageViewer.prefetch(uris);
bigImageView.setImageSaveCallback(new ImageSaveCallback() {
@Override
public void onSuccess(String uri) {
Toast.makeText(LongImageActivity.this,
"Success",
Toast.LENGTH_SHORT).show();
}
@Override
public void onFail(Throwable t) {
t.printStackTrace();
Toast.makeText(LongImageActivity.this,
"Fail",
Toast.LENGTH_SHORT).show();
}
});
// should be called on worker/IO thread
bigImageView.saveImageIntoGallery();
// only valid when image file is downloaded.
File path = bigImageView.getCurrentImageFile();
You can set the normal image scale type using initScaleType attribute, or setInitScaleType.
mBigImageView.setInitScaleType(BigImageView.INIT_SCALE_TYPE_CENTER_CROP);
| value | effect |
|---|---|
| center | Center the image in the view, but perform no scaling. |
| centerCrop | Scale the image uniformly (maintain the image's aspect ratio) so that both dimensions (width and height) of the image will be equal to or larger than the corresponding dimension of the view (minus padding). The image is then centered in the view. |
| centerInside | Scale the image uniformly (maintain the image's aspect ratio) so that both dimensions (width and height) of the image will be equal to or less than the corresponding dimension of the view (minus padding). The image is then centered in the view. |
| fitCenter | Scales the image so that it fits entirely inside the parent. At least one dimension (width or height) will fit exactly. Aspect ratio is preserved. Image is centered within the parent's bounds. |
| fitEnd | Scales the image so that it fits entirely inside the parent. At least one dimension (width or height) will fit exactly. Aspect ratio is preserved. Image is aligned to the bottom-right corner of the parent. |
| fitStart | Scales the image so that it fits entirely inside the parent. At least one dimension (width or height) will fit exactly. Aspect ratio is preserved. Image is aligned to the top-left corner of the parent. |
| fitXY | Scales width and height independently, so that the image matches the parent exactly. This may change the aspect ratio of the image. |
| custom | Scale the image so that both dimensions of the image will be equal to or less than the maxScale and equal to or larger than minScale. The image is then centered in the view. |
| start | Scale the image so that both dimensions of the image will be equal to or larger than the corresponding dimension of the view. The top left is shown. |
Note: SSIV only support centerCrop, centerInside, custom and start, other scale types are treated as centerInside, while other scale types may be used by animated image types.
You can set a local failure image using failureImage attribute, or setFailureImage.
It will displayed using an ImageView when the image network request fails. If not specified,
nothing is displayed when the request fails.
You can set the failure image scale type using failureImageInitScaleType attribute,
or setFailureImageInitScaleType.
Any value of ImageView.ScaleType
is valid. Default value is ImageView.ScaleType.FIT_CENTER. It will be ignored if there is
no failure image set.
When failure image is specified, you can tap the failure image then it will retry automatically.
That's the default behavior, you can change it using tapToRetry attribute, or setTapToRetry.
You can handle the image load response by creating a new ImageLoader.Callback
and overriding the key callbacks
…
Then setting it as the image load callback
mBigImageView.setImageLoaderCallback(myImageLoaderCallback);
The onSuccess(File image) is always called after the image was retrieved
successfully whether from the cache or the network.
For an example, see ImageLoaderCallbackActivity.java
BIV will cancel image loading automatically when detach from window, you can also call cancel
to cancel it manually.
You can also call BigImageViewer.imageLoader().cancelAll(); in an appropriate time,
e.g. Activity/Fragment's onDestroy callback, to cancel all flying requests, avoiding memory leak.
You can get the SSIV instance through the method below:
public SubsamplingScaleImageView getSSIV() {
return mImageView;
}
Then you can do anything you can imagine about SSIV :)
Note: you should test whether SSIV is null, because the image could be a gif, then it won't be displayed by SSIV.
You can even use your own custom SSIV, by calling biv.setImageViewFactory(),
passing in a factory that override createStillImageView, and return your custom SSIV.
You can use your custom Glide's components. If you have customized your Glide's configuration, you are able to apply that configuration to BIV too, to do that you only have to initialize BIV in this way:
BigImageViewer.initialize(GlideCustomImageLoader.with(appContext, CustomComponentModel.class));
Where CustomComponentModel.class is the Glide's model component. That's it!
For more detailed example, please refer to the example project.
Handle permission when you want to save image into gallery.
When you want load local image file, you can create the Uri via
Uri.fromFile, but the path will be url encoded, and may cause the image loader
fail to load it, consider using Uri.parse("file://" + file.getAbsolutePath()).
When using with RecyclerView or ViewPager, the recycled BIV doesn't know it should clear the loaded image or reload the image, so you need manually notify it in some way, see issue 107, and issue 177.
Crash on Android 4.x device? You could force gradle to use a specific version of OkHttp (some version earlier than 3.13.0), by adding this block to your module's build.gradle, please note that it should be added at the top level, not inside any other block:
configurations {
all {
resolutionStrategy {
eachDependency { DependencyResolveDetails details ->
if (details.requested.group == 'com.squareup.okhttp3' &&
details.requested.name ==
'okhttp') {
// OkHttp drops support before 5.0 since 3.13.0
details.useVersion '3.12.6'
}
}
}
}
}
There are several big image viewer libraries, PhotoDraweeView, FrescoImageViewer, and Subsampling Scale Image View.
They both support pan and zoom. PhotoDraweeView and FrescoImageViewer both use
暂无开放 Issues,或尚未同步最近议题。