Skip to content

Commit 5404ff9

Browse files
KirkBushmanPiasy
authored andcommitted
shared animation works and test, fixed warnings and test app (#175)
* shared animation works and test, fixed warnings and test app * fixed naming schemes, passed view through ImageViewFactory
1 parent 7611327 commit 5404ff9

22 files changed

+440
-144
lines changed

BigImageViewer/src/main/java/com/github/piasy/biv/view/BigImageView.java

Lines changed: 79 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,10 @@ public class BigImageView extends FrameLayout implements ImageLoader.Callback {
9898
private View mProgressIndicatorView;
9999
private ImageView mFailureImageView;
100100

101+
private boolean mDelayMainImage = false;
102+
101103
private ImageSaveCallback mImageSaveCallback;
104+
private ImageShownCallback mImageShownCallback;
102105
private ImageLoader.Callback mUserCallback;
103106
private File mCurrentImageFile;
104107
private Uri mUri;
@@ -286,6 +289,10 @@ public void setImageSaveCallback(ImageSaveCallback imageSaveCallback) {
286289
mImageSaveCallback = imageSaveCallback;
287290
}
288291

292+
public void setImageShownCallback(ImageShownCallback imageCycleCallback) {
293+
mImageShownCallback = imageCycleCallback;
294+
}
295+
289296
public void setProgressIndicator(ProgressIndicator progressIndicator) {
290297
mProgressIndicator = progressIndicator;
291298
}
@@ -342,17 +349,34 @@ public void showImage(Uri uri) {
342349
}
343350

344351
public void showImage(final Uri thumbnail, final Uri uri) {
352+
showImage(thumbnail, uri, false);
353+
}
354+
355+
public void showImage(final Uri thumbnail, final Uri uri, final boolean delayMainImage) {
345356
mThumbnail = thumbnail;
346357
mUri = uri;
347358

348359
clearThumbnailAndProgressIndicator();
349-
mImageLoader.loadImage(hashCode(), uri, mInternalCallback);
360+
361+
mDelayMainImage = delayMainImage;
362+
if (mDelayMainImage) {
363+
BigImageViewer.prefetch(uri);
364+
mImageLoader.loadImage(hashCode(), thumbnail, mInternalCallback);
365+
} else {
366+
mImageLoader.loadImage(hashCode(), uri, mInternalCallback);
367+
}
350368

351369
if (mFailureImageView != null) {
352370
mFailureImageView.setVisibility(GONE);
353371
}
354372
}
355373

374+
public void loadMainImageNow() {
375+
376+
mDelayMainImage = false;
377+
mImageLoader.loadImage(hashCode(), mUri, mInternalCallback);
378+
}
379+
356380
public void cancel() {
357381
mImageLoader.cancel(hashCode());
358382
}
@@ -362,9 +386,9 @@ public SubsamplingScaleImageView getSSIV() {
362386
}
363387

364388
@Override
365-
public void onCacheHit(final int imageType, File image) {
389+
public void onCacheHit(final int imageType, final File image) {
366390
mCurrentImageFile = image;
367-
doShowImage(imageType, image);
391+
doShowImage(imageType, image, mDelayMainImage);
368392

369393
if (mUserCallback != null) {
370394
mUserCallback.onCacheHit(imageType, image);
@@ -375,7 +399,7 @@ public void onCacheHit(final int imageType, File image) {
375399
public void onCacheMiss(final int imageType, final File image) {
376400
mCurrentImageFile = image;
377401
mTempImages.add(image);
378-
doShowImage(imageType, image);
402+
doShowImage(imageType, image, mDelayMainImage);
379403

380404
if (mUserCallback != null) {
381405
mUserCallback.onCacheMiss(imageType, image);
@@ -502,32 +526,63 @@ public void onAnimationRepeat(Animation animation) {
502526
}
503527

504528
@UiThread
505-
private void doShowImage(final int imageType, final File image) {
506-
if (mMainView != null) {
507-
removeView(mMainView);
508-
}
529+
private void doShowImage(final int imageType, final File image, final boolean useThumbnailView) {
509530

510-
mMainView = mViewFactory.createMainView(getContext(), imageType, image, mInitScaleType);
511-
if (mMainView == null) {
512-
onFail(new RuntimeException("Image type not supported: "
513-
+ ImageInfoExtractor.typeName(imageType)));
514-
return;
515-
}
531+
if (useThumbnailView) {
532+
533+
if(mThumbnailView != null) {
534+
removeView(mThumbnailView);
535+
}
516536

517-
addView(mMainView, ViewGroup.LayoutParams.MATCH_PARENT,
518-
ViewGroup.LayoutParams.MATCH_PARENT);
519-
mMainView.setOnClickListener(mOnClickListener);
520-
mMainView.setOnLongClickListener(mOnLongClickListener);
537+
mThumbnailView = mViewFactory.createThumbnailView(getContext(), Uri.fromFile(image), mThumbnailScaleType);
538+
if (mThumbnailView != null) {
539+
540+
addView(mThumbnailView, ViewGroup.LayoutParams.MATCH_PARENT,
541+
ViewGroup.LayoutParams.MATCH_PARENT);
542+
mThumbnailView.setOnClickListener(mOnClickListener);
543+
mThumbnailView.setOnLongClickListener(mOnLongClickListener);
544+
545+
((ImageView) mThumbnailView).setAdjustViewBounds(true);
546+
((ImageView) mThumbnailView).setScaleType(ImageView.ScaleType.FIT_START);
547+
((ImageView) mThumbnailView).setImageURI(Uri.fromFile(image));
548+
549+
if (mImageShownCallback != null) {
550+
mImageShownCallback.onThumbnailShown();
551+
}
552+
}
553+
554+
} else {
555+
556+
if (mMainView != null) {
557+
removeView(mMainView);
558+
}
559+
560+
mMainView = mViewFactory.createMainView(getContext(), imageType, image, mInitScaleType);
561+
if (mMainView == null) {
562+
onFail(new RuntimeException("Image type not supported: "
563+
+ ImageInfoExtractor.typeName(imageType)));
564+
return;
565+
}
521566

522-
if (mMainView instanceof SubsamplingScaleImageView) {
523-
mSSIV = (SubsamplingScaleImageView) mMainView;
567+
addView(mMainView, ViewGroup.LayoutParams.MATCH_PARENT,
568+
ViewGroup.LayoutParams.MATCH_PARENT);
569+
mMainView.setOnClickListener(mOnClickListener);
570+
mMainView.setOnLongClickListener(mOnLongClickListener);
524571

525-
mSSIV.setMinimumTileDpi(160);
572+
if (mMainView instanceof SubsamplingScaleImageView) {
573+
mSSIV = (SubsamplingScaleImageView) mMainView;
526574

527-
setOptimizeDisplay(mOptimizeDisplay);
528-
setInitScaleType(mInitScaleType);
575+
mSSIV.setMinimumTileDpi(160);
529576

530-
mSSIV.setImage(ImageSource.uri(Uri.fromFile(image)));
577+
setOptimizeDisplay(mOptimizeDisplay);
578+
setInitScaleType(mInitScaleType);
579+
580+
mSSIV.setImage(ImageSource.uri(Uri.fromFile(image)));
581+
582+
if (mImageShownCallback != null) {
583+
mImageShownCallback.onMainImageShown();
584+
}
585+
}
531586
}
532587

533588
if (mFailureImageView != null) {
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.github.piasy.biv.view;
2+
3+
import androidx.annotation.UiThread;
4+
5+
@UiThread
6+
public interface ImageShownCallback {
7+
8+
void onThumbnailShown();
9+
void onMainImageShown();
10+
}

BigImageViewer/src/main/java/com/github/piasy/biv/view/ImageViewFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,6 @@ protected View createAnimatedImageView(Context context, int imageType, File imag
6060
}
6161

6262
public View createThumbnailView(Context context, Uri thumbnail, ImageView.ScaleType scaleType) {
63-
return null;
63+
return new ImageView(context);
6464
}
6565
}

app/build.gradle

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
apply plugin: 'com.android.application'
2626
apply plugin: 'com.github.ben-manes.versions'
27+
apply plugin: 'kotlin-android'
2728

2829
android {
2930
compileSdkVersion rootProject.ext.androidCompileSdkVersion
@@ -72,8 +73,9 @@ android {
7273
}
7374

7475
dependencies {
76+
implementation "androidx.core:core-ktx:1.1.0"
7577
implementation "androidx.appcompat:appcompat:1.1.0"
76-
implementation "androidx.recyclerview:recyclerview:1.0.0"
78+
implementation "androidx.recyclerview:recyclerview:1.1.0-beta05"
7779
implementation "com.google.android.material:material:$materialVersion"
7880

7981
implementation('com.tbruyelle.rxpermissions2:rxpermissions:0.9.5') {

app/src/main/AndroidManifest.xml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@
2323
~ SOFTWARE.
2424
-->
2525
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
26-
xmlns:tools="http://schemas.android.com/tools"
27-
package="com.github.piasy.biv.example">
26+
package="com.github.piasy.biv.example">
2827

2928
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
3029

@@ -52,6 +51,8 @@
5251
<activity android:name=".CustomSSIVActivity"/>
5352
<activity android:name=".RecyclerViewActivity"/>
5453
<activity android:name=".ImageTypesActivity"/>
54+
<activity android:name=".FirstAnimActivity" android:theme="@style/TransitionTheme"/>
55+
<activity android:name=".SecondAnimActivity" android:theme="@style/TransitionTheme"/>
5556
</application>
5657

5758
</manifest>
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.github.piasy.biv.example
2+
3+
import android.os.Bundle
4+
import android.widget.ImageView
5+
import androidx.appcompat.app.AppCompatActivity
6+
import com.bumptech.glide.Glide
7+
import com.bumptech.glide.load.engine.DiskCacheStrategy
8+
9+
class FirstAnimActivity : AppCompatActivity() {
10+
11+
companion object {
12+
private const val THUMB_URL = "https://preview.redd.it/nahhvcadsbo21.jpg?width=216&crop=smart&auto=webp&s=c560e5774d7f43e178c1f0faad09315cdb86c203"
13+
private const val SOURCE_URL = "https://i.redd.it/nahhvcadsbo21.jpg"
14+
}
15+
16+
override fun onCreate(savedInstanceState: Bundle?) {
17+
super.onCreate(savedInstanceState)
18+
setContentView(R.layout.activity_anim_first)
19+
20+
val thumb = findViewById<ImageView>(R.id.thumbView)
21+
thumb.setOnClickListener {
22+
23+
SecondAnimActivity.start(this, thumb, THUMB_URL, SOURCE_URL)
24+
}
25+
26+
val glide = Glide.with(this)
27+
glide.asBitmap()
28+
.load(THUMB_URL)
29+
.into(thumb)
30+
}
31+
}

app/src/main/java/com/github/piasy/biv/example/LongImageActivity.java

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,16 @@
2525
package com.github.piasy.biv.example;
2626

2727
import android.Manifest;
28-
import android.app.Dialog;
2928
import android.net.Uri;
3029
import android.os.Bundle;
30+
import android.view.LayoutInflater;
3131
import android.view.View;
32+
import android.view.ViewGroup;
3233
import android.view.WindowManager;
3334
import android.widget.TextView;
3435
import android.widget.Toast;
3536

37+
import androidx.appcompat.app.AlertDialog;
3638
import androidx.appcompat.app.AppCompatActivity;
3739

3840
import com.github.piasy.biv.BigImageViewer;
@@ -55,7 +57,7 @@ public class LongImageActivity extends AppCompatActivity {
5557
private Disposable mPermissionRequest;
5658
private Disposable mQrCodeDecode;
5759

58-
private Dialog dialog;
60+
private AlertDialog dialog;
5961

6062
@Override
6163
protected void onCreate(Bundle savedInstanceState) {
@@ -73,36 +75,13 @@ public void onClick(View v) {
7375
}
7476
});
7577

76-
dialog = new Dialog(this);
77-
dialog.setTitle(R.string.long_click_actions);
78-
dialog.setContentView(R.layout.dialog_long_image);
79-
80-
final WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
81-
lp.copyFrom(dialog.getWindow().getAttributes());
82-
lp.width = WindowManager.LayoutParams.MATCH_PARENT;
83-
dialog.getWindow().setAttributes(lp);
84-
85-
final TextView textScan = dialog.findViewById(R.id.action_scan_qr);
86-
final TextView textSave = dialog.findViewById(R.id.action_save_image);
87-
88-
textScan.setOnClickListener(new View.OnClickListener() {
89-
@Override
90-
public void onClick(View v) {
91-
decodeQrCode();
92-
}
93-
});
94-
95-
textSave.setOnClickListener(new View.OnClickListener() {
96-
@Override
97-
public void onClick(View v) {
98-
saveImage();
99-
}
100-
});
101-
10278
mBigImageView.setOnLongClickListener(new View.OnLongClickListener() {
10379
@Override
10480
public boolean onLongClick(View v) {
81+
82+
dialog = showDialog();
10583
dialog.show();
84+
10685
return true;
10786
}
10887
});
@@ -141,10 +120,6 @@ protected void onDestroy() {
141120
disposePermissionRequest();
142121
disposeQrCodeDecode();
143122

144-
if (dialog.isShowing()) {
145-
dialog.dismiss();
146-
}
147-
148123
BigImageViewer.imageLoader().cancelAll();
149124
}
150125

@@ -195,6 +170,33 @@ public void accept(Throwable throwable) throws Exception {
195170
});
196171
}
197172

173+
private AlertDialog showDialog() {
174+
175+
final ViewGroup container = findViewById(R.id.container);
176+
final AlertDialog.Builder builder = new AlertDialog.Builder(LongImageActivity.this);
177+
final View rootView = LayoutInflater.from(LongImageActivity.this).inflate(R.layout.dialog_long_image, container, false);
178+
builder.setView(rootView);
179+
180+
final TextView textScan = rootView.findViewById(R.id.action_scan_qr);
181+
final TextView textSave = rootView.findViewById(R.id.action_save_image);
182+
183+
textScan.setOnClickListener(new View.OnClickListener() {
184+
@Override
185+
public void onClick(View v) {
186+
decodeQrCode();
187+
}
188+
});
189+
190+
textSave.setOnClickListener(new View.OnClickListener() {
191+
@Override
192+
public void onClick(View v) {
193+
saveImage();
194+
}
195+
});
196+
197+
return builder.create();
198+
}
199+
198200
private void disposePermissionRequest() {
199201
if (mPermissionRequest != null) {
200202
mPermissionRequest.dispose();

app/src/main/java/com/github/piasy/biv/example/MainActivity.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,5 +84,11 @@ public void onClick(View v) {
8484
startActivity(new Intent(MainActivity.this, ImageTypesActivity.class));
8585
}
8686
});
87+
findViewById(R.id.mSharedTransition).setOnClickListener(new View.OnClickListener() {
88+
@Override
89+
public void onClick(View v) {
90+
startActivity(new Intent(MainActivity.this, FirstAnimActivity.class));
91+
}
92+
});
8793
}
8894
}

0 commit comments

Comments
 (0)