Skip to content

Commit 642ed51

Browse files
authored
Fixes #3414: For v2.13, Handle zoom in media details view (#3422)
* MediaDetailFragment: add zoom feature * fragment_media_detail: add SimpleDrawee for Scroll picture * ZoomableActivity: activity which facilitates zoom in * activity_zoomable: xml for zoom activity * zoomControllers: controllers for handling gesture and zooming * MediaDetailFragment: fixing name of image variable * MediaDetailFragment: display as per the aspect ratio of image * add zoom activity to AndroidManifest * fix travis ci faliure * fix resizing of image
1 parent 5fd88ef commit 642ed51

16 files changed

+2295
-32
lines changed

app/src/main/AndroidManifest.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@
4141
android:excludeFromRecents="true"
4242
android:finishOnTaskLaunch="true" />
4343

44+
<activity
45+
android:name=".media.ZoomableActivity" />
46+
4447
<activity android:name=".auth.LoginActivity">
4548
<intent-filter>
4649
<category android:name="android.intent.category.LAUNCHER" />

app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package fr.free.nrw.commons.media;
22

33
import android.annotation.SuppressLint;
4+
import android.graphics.drawable.Animatable;
45
import android.app.AlertDialog;
56
import android.content.Intent;
7+
import android.content.Context;
68
import android.net.Uri;
79
import android.os.Bundle;
810
import android.text.Editable;
@@ -23,7 +25,10 @@
2325

2426
import com.facebook.drawee.backends.pipeline.Fresco;
2527
import com.facebook.drawee.interfaces.DraweeController;
28+
import com.facebook.drawee.controller.BaseControllerListener;
29+
import com.facebook.drawee.controller.ControllerListener;
2630
import com.facebook.drawee.view.SimpleDraweeView;
31+
import com.facebook.imagepipeline.image.ImageInfo;
2732
import com.facebook.imagepipeline.request.ImageRequest;
2833

2934
import org.apache.commons.lang3.StringUtils;
@@ -39,6 +44,7 @@
3944
import butterknife.BindView;
4045
import butterknife.ButterKnife;
4146
import butterknife.OnClick;
47+
import androidx.annotation.Nullable;
4248
import fr.free.nrw.commons.Media;
4349
import fr.free.nrw.commons.MediaDataExtractor;
4450
import fr.free.nrw.commons.R;
@@ -97,10 +103,8 @@ public static MediaDetailFragment forMedia(int index, boolean editable, boolean
97103

98104
private int initialListTop = 0;
99105

100-
@BindView(R.id.mediaDetailImage)
106+
@BindView(R.id.mediaDetailImageView)
101107
SimpleDraweeView image;
102-
@BindView(R.id.mediaDetailSpacer)
103-
MediaDetailSpacer spacer;
104108
@BindView(R.id.mediaDetailTitle)
105109
TextView title;
106110
@BindView(R.id.mediaDetailDesc)
@@ -197,36 +201,18 @@ && getParentFragment() instanceof MediaDetailPagerFragment) {
197201
// Progressively darken the image in the background when we scroll detail pane up
198202
scrollListener = this::updateTheDarkness;
199203
view.getViewTreeObserver().addOnScrollChangedListener(scrollListener);
200-
201-
// Layout layoutListener to size the spacer item relative to the available space.
202-
// There may be a .... better way to do this.
203-
layoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
204-
private int currentHeight = -1;
205-
206-
@Override
207-
public void onGlobalLayout() {
208-
int viewHeight = view.getHeight();
209-
//int textHeight = title.getLineHeight();
210-
int paddingDp = 112;
211-
float paddingPx = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, paddingDp, getResources().getDisplayMetrics());
212-
int newHeight = viewHeight - Math.round(paddingPx);
213-
214-
if (newHeight != currentHeight) {
215-
currentHeight = newHeight;
216-
ViewGroup.LayoutParams params = spacer.getLayoutParams();
217-
params.height = newHeight;
218-
spacer.setLayoutParams(params);
219-
220-
scrollView.scrollTo(0, initialListTop);
221-
}
222-
}
223-
};
224-
view.getViewTreeObserver().addOnGlobalLayoutListener(layoutListener);
225204
locale = getResources().getConfiguration().locale;
226-
227205
return view;
228206
}
229207

208+
@OnClick(R.id.mediaDetailImageView)
209+
public void launchZoomActivity(View view) {
210+
Context ctx = view.getContext();
211+
ctx.startActivity(
212+
new Intent(ctx,ZoomableActivity.class).setData(Uri.parse(media.getImageUrl()))
213+
);
214+
}
215+
230216
@Override
231217
public void onResume() {
232218
super.onResume();
@@ -255,6 +241,26 @@ private void displayMediaDetails() {
255241
compositeDisposable.add(disposable);
256242
}
257243

244+
private void updateAspectRatio(ImageInfo imageInfo) {
245+
if (imageInfo != null) {
246+
int finalHeight = (scrollView.getWidth()*imageInfo.getHeight()) / imageInfo.getWidth();
247+
ViewGroup.LayoutParams params = image.getLayoutParams();
248+
params.height = finalHeight;
249+
image.setLayoutParams(params);
250+
}
251+
}
252+
253+
private final ControllerListener aspectRatioListener = new BaseControllerListener<ImageInfo>() {
254+
@Override
255+
public void onIntermediateImageSet(String id, @Nullable ImageInfo imageInfo) {
256+
updateAspectRatio(imageInfo);
257+
}
258+
@Override
259+
public void onFinalImageSet(String id, @Nullable ImageInfo imageInfo, @Nullable Animatable animatable) {
260+
updateAspectRatio(imageInfo);
261+
}
262+
};
263+
258264
/**
259265
* Uses two image sources.
260266
* - low resolution thumbnail is shown initially
@@ -264,6 +270,7 @@ private void setupImageView() {
264270
DraweeController controller = Fresco.newDraweeControllerBuilder()
265271
.setLowResImageRequest(ImageRequest.fromUri(media.getThumbUrl()))
266272
.setImageRequest(ImageRequest.fromUri(media.getImageUrl()))
273+
.setControllerListener(aspectRatioListener)
267274
.setOldController(image.getController())
268275
.build();
269276
image.setController(controller);
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package fr.free.nrw.commons.media;
2+
3+
import androidx.annotation.NonNull;
4+
import androidx.annotation.Nullable;
5+
import androidx.appcompat.app.AppCompatActivity;
6+
import butterknife.BindView;
7+
import butterknife.ButterKnife;
8+
import fr.free.nrw.commons.R;
9+
import fr.free.nrw.commons.media.zoomControllers.zoomable.DoubleTapGestureListener;
10+
import fr.free.nrw.commons.media.zoomControllers.zoomable.ZoomableDraweeView;
11+
import timber.log.Timber;
12+
13+
import android.graphics.Bitmap;
14+
import android.graphics.BitmapFactory;
15+
import android.net.Uri;
16+
import android.os.Bundle;
17+
import com.facebook.drawee.backends.pipeline.Fresco;
18+
import com.facebook.drawee.interfaces.DraweeController;
19+
import android.view.LayoutInflater;
20+
import android.view.View;
21+
import android.view.ViewGroup;
22+
23+
import com.facebook.drawee.view.SimpleDraweeView;
24+
import com.github.chrisbanes.photoview.PhotoView;
25+
26+
import java.io.InputStream;
27+
import java.net.HttpURLConnection;
28+
import java.net.URL;
29+
30+
public class ZoomableActivity extends AppCompatActivity {
31+
private Uri imageUri;
32+
33+
@BindView(R.id.zoomable)
34+
ZoomableDraweeView photo;
35+
36+
@Override
37+
protected void onCreate(Bundle savedInstanceState) {
38+
super.onCreate(savedInstanceState);
39+
40+
imageUri = getIntent().getData();
41+
if (null == imageUri) {
42+
throw new IllegalArgumentException("No data to display");
43+
}
44+
Timber.d("URl = " + imageUri);
45+
46+
setContentView(R.layout.activity_zoomable);
47+
ButterKnife.bind(this);
48+
init();
49+
}
50+
51+
private void init() {
52+
if( imageUri != null ) {
53+
photo.setAllowTouchInterceptionWhileZoomed(true);
54+
photo.setIsLongpressEnabled(false);
55+
photo.setTapListener(new DoubleTapGestureListener(photo));
56+
DraweeController controller = Fresco.newDraweeControllerBuilder()
57+
.setUri(imageUri)
58+
.build();
59+
photo.setController(controller);
60+
}
61+
}
62+
63+
64+
}

0 commit comments

Comments
 (0)