修改图片详情页面的实现方式,适配大图/长图
This commit is contained in:
@ -1,11 +1,12 @@
|
||||
package com.gh.gamecenter;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Color;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
@ -18,40 +19,39 @@ import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.facebook.binaryresource.BinaryResource;
|
||||
import com.facebook.cache.common.CacheKey;
|
||||
import com.facebook.common.executors.CallerThreadExecutor;
|
||||
import com.facebook.common.references.CloseableReference;
|
||||
import com.facebook.datasource.DataSource;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.viewpager.widget.PagerAdapter;
|
||||
import androidx.viewpager.widget.ViewPager.OnPageChangeListener;
|
||||
|
||||
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView;
|
||||
import com.facebook.drawee.backends.pipeline.Fresco;
|
||||
import com.facebook.drawee.interfaces.DraweeController;
|
||||
import com.facebook.imagepipeline.core.ImagePipeline;
|
||||
import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber;
|
||||
import com.facebook.imagepipeline.image.CloseableImage;
|
||||
import com.facebook.imagepipeline.request.ImageRequest;
|
||||
import com.facebook.imagepipeline.request.ImageRequestBuilder;
|
||||
import com.gh.base.BaseActivity;
|
||||
import com.gh.common.Base64ImageHolder;
|
||||
import com.gh.common.util.DisplayUtils;
|
||||
import com.gh.common.util.EntranceUtils;
|
||||
import com.gh.common.util.ImageUtils;
|
||||
import com.gh.common.util.MD5Utils;
|
||||
import com.gh.common.util.MessageShareUtils;
|
||||
import com.gh.common.util.NetworkUtils;
|
||||
import com.gh.common.util.PermissionHelper;
|
||||
import com.gh.common.view.EmptyDrawable;
|
||||
import com.gh.common.util.SimpleImageLoader;
|
||||
import com.gh.common.view.Gh_RelativeLayout;
|
||||
import com.gh.common.view.Gh_RelativeLayout.OnSingleTapListener;
|
||||
import com.gh.common.view.Gh_ViewPager;
|
||||
import com.gh.common.view.ZoomSimpleDraweeView;
|
||||
import com.gh.gamecenter.entity.ImageInfoEntity;
|
||||
import com.gh.gamecenter.retrofit.Response;
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager;
|
||||
import com.github.piasy.biv.view.BigImageView;
|
||||
import com.github.piasy.biv.view.FrescoImageViewFactory;
|
||||
import com.lightgame.utils.Utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@ -59,11 +59,6 @@ import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.viewpager.widget.PagerAdapter;
|
||||
import androidx.viewpager.widget.ViewPager.OnPageChangeListener;
|
||||
import butterknife.BindView;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
@ -90,14 +85,13 @@ public class ViewImageActivity extends BaseActivity implements OnPageChangeListe
|
||||
private ViewImageAdapter adapter;
|
||||
|
||||
private ImagePipeline mImagePipeline;
|
||||
|
||||
|
||||
private boolean mShowBase64Image = false;
|
||||
|
||||
private static final String KEY_BASE64 = "base64";
|
||||
|
||||
|
||||
private static final String KEY_URLS = "urls";
|
||||
private static final String KEY_CURRENT = "current";
|
||||
private static final String KEY_SCALETYPE = "ScaleType";
|
||||
|
||||
private ArrayList<String> urls;
|
||||
private HashSet<Integer> mViewedSet; // 让调用者知道该图片是否被看过了
|
||||
@ -106,7 +100,7 @@ public class ViewImageActivity extends BaseActivity implements OnPageChangeListe
|
||||
private int mLimitWidth;
|
||||
|
||||
private boolean isOrientation;
|
||||
|
||||
|
||||
public static Intent getBase64ViewImageIntent(Context context, boolean showSingleBase64Image) {
|
||||
Intent checkIntent = new Intent(context, ViewImageActivity.class);
|
||||
checkIntent.putExtra(KEY_BASE64, showSingleBase64Image);
|
||||
@ -131,7 +125,6 @@ public class ViewImageActivity extends BaseActivity implements OnPageChangeListe
|
||||
super.onCreate(savedInstanceState);
|
||||
mViewedSet = new HashSet<>();
|
||||
mImageInfoMap = new HashMap<>();
|
||||
|
||||
// init data
|
||||
int current = 0;
|
||||
Bundle extras = getIntent().getExtras();
|
||||
@ -183,31 +176,29 @@ public class ViewImageActivity extends BaseActivity implements OnPageChangeListe
|
||||
if (object != null) {
|
||||
mProgressHint.setWidth(mProgressHint.getWidth());
|
||||
RelativeLayout view = (RelativeLayout) object;
|
||||
final ZoomSimpleDraweeView draweeView = view.findViewById(R.id.viewimage_iv_show);
|
||||
draweeView.getHierarchy().setProgressBarImage(new EmptyDrawable(progress -> {
|
||||
if (position == mViewPager.getCurrentItem()) { // 防止下载过程中切换图片
|
||||
int percent = progress / 100;
|
||||
if (percent < 100) {
|
||||
mProgressHint.setText((percent + "%"));
|
||||
} else {
|
||||
mProgressHint.setText("已完成");
|
||||
mBaseHandler.postDelayed(() -> {
|
||||
if (position == mViewPager.getCurrentItem()) { // 防止等待过程中切换图片
|
||||
mProgressHint.setVisibility(View.GONE);
|
||||
}
|
||||
}, 500);
|
||||
final BigImageView imageView = view.findViewById(R.id.viewimage_iv_show);
|
||||
String url = urls.get(position);
|
||||
imageView.showImage(Uri.parse(url));
|
||||
imageView.setImageLoaderCallback(new SimpleImageLoader() {
|
||||
@Override
|
||||
public void onProgress(int progress) {
|
||||
if (position == mViewPager.getCurrentItem()) { // 防止下载过程中切换图片
|
||||
if (progress < 100) {
|
||||
mProgressHint.setText((progress + "%"));
|
||||
} else {
|
||||
mProgressHint.setText("已完成");
|
||||
mBaseHandler.postDelayed(() -> {
|
||||
if (position == mViewPager.getCurrentItem()) { // 防止等待过程中切换图片
|
||||
mProgressHint.setVisibility(View.GONE);
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
draweeView.setController(Fresco.newDraweeControllerBuilder()
|
||||
// 高清图片
|
||||
.setImageRequest(ImageRequest.fromUri(urls.get(position)))
|
||||
// 低分辨率图片
|
||||
.setLowResImageRequest(ImageRequest.fromUri(ImageUtils.addLimitWidth(urls.get(position), mLimitWidth)))
|
||||
.build());
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
DisplayUtils.transparentStatusAndNavigation(this);
|
||||
}
|
||||
|
||||
@ -263,8 +254,10 @@ public class ViewImageActivity extends BaseActivity implements OnPageChangeListe
|
||||
return;
|
||||
}
|
||||
|
||||
ZoomSimpleDraweeView zoomDraweeView = ghRelativeLayout.findViewById(R.id.viewimage_iv_show);
|
||||
zoomDraweeView.reset(); // 重置矩阵,还原图片
|
||||
BigImageView imageView = ghRelativeLayout.findViewById(R.id.viewimage_iv_show);
|
||||
SubsamplingScaleImageView ssiv = imageView.getSSIV();
|
||||
if (ssiv != null) ssiv.resetScaleAndCenter();
|
||||
|
||||
}
|
||||
}
|
||||
mIndicatorTv.setText(String.format("%d/%d", position + 1, urls.size()));
|
||||
@ -295,16 +288,10 @@ public class ViewImageActivity extends BaseActivity implements OnPageChangeListe
|
||||
});
|
||||
}
|
||||
|
||||
private void loadImage(String url, final ZoomSimpleDraweeView imageView) {
|
||||
if (url.contains(".gif")) {
|
||||
DraweeController controller = Fresco.newDraweeControllerBuilder()
|
||||
.setUri(url)
|
||||
.setAutoPlayAnimations(true)
|
||||
.build();
|
||||
imageView.setController(controller);
|
||||
} else {
|
||||
imageView.setImageURI(url); // 加载原图
|
||||
}
|
||||
private void loadImage(String url, final BigImageView imageView) {
|
||||
// 添加GIF支持
|
||||
imageView.setImageViewFactory(new FrescoImageViewFactory());
|
||||
imageView.showImage(Uri.parse(url));
|
||||
}
|
||||
|
||||
private class ViewImageAdapter extends PagerAdapter implements OnSingleTapListener {
|
||||
@ -317,6 +304,7 @@ public class ViewImageActivity extends BaseActivity implements OnPageChangeListe
|
||||
return urls.size();
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
@NonNull
|
||||
@Override
|
||||
public Object instantiateItem(@NonNull ViewGroup container, int position) {
|
||||
@ -324,28 +312,45 @@ public class ViewImageActivity extends BaseActivity implements OnPageChangeListe
|
||||
ImageRequest imageRequest = ImageRequest.fromUri(url);
|
||||
boolean isInMemoryCache = mImagePipeline.isInBitmapMemoryCache(imageRequest);
|
||||
boolean isInDiskCache = imageRequest != null && mImagePipeline.isInDiskCacheSync(imageRequest);
|
||||
|
||||
Gh_RelativeLayout view = (Gh_RelativeLayout) View.inflate(container.getContext(), R.layout.viewimage_normal_item, null);
|
||||
ZoomSimpleDraweeView imageView = view.findViewById(R.id.viewimage_iv_show);
|
||||
|
||||
if (isInMemoryCache
|
||||
|| isInDiskCache
|
||||
|| NetworkUtils.isWifiOr4GConnected(ViewImageActivity.this)
|
||||
|| url.contains(".gif")) {
|
||||
loadImage(url, imageView);
|
||||
} else {
|
||||
ImageUtils.addLimitWidthAndLoad(imageView, url, mLimitWidth, imageInfo -> {
|
||||
if (imageInfo != null && mImageInfoMap.get(url) == null) {
|
||||
loadImageInfo(position, imageInfo.getWidth()); // 加载图片参数,目的是用户显示原文按钮
|
||||
}
|
||||
});
|
||||
Gh_RelativeLayout view = (Gh_RelativeLayout) View.inflate(container.getContext(), R.layout.viewimage_normal_item, null);
|
||||
BigImageView imageView = view.findViewById(R.id.viewimage_iv_show);
|
||||
|
||||
if (!isInMemoryCache
|
||||
&& !isInDiskCache
|
||||
&& !NetworkUtils.isWifiOr4GConnected(ViewImageActivity.this)
|
||||
&& !url.contains(".gif")) {
|
||||
url = ImageUtils.getTransformLimitUrl(url, mLimitWidth, getApplicationContext());
|
||||
}
|
||||
|
||||
//单点退出
|
||||
imageView.setOnSingleClickListener(ViewImageActivity.this::finish);
|
||||
String finalUrl = url;
|
||||
imageView.setImageLoaderCallback(new SimpleImageLoader() {
|
||||
@Override
|
||||
public void onSuccess(File image) {
|
||||
if (!finalUrl.equals(urls.get(position))) {
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
options.inJustDecodeBounds = true;
|
||||
BitmapFactory.decodeFile(new File(image.getPath()).getAbsolutePath(), options);
|
||||
loadImageInfo(position, options.outWidth); // 加载图片参数,目的是用户显示原文按钮
|
||||
}
|
||||
SubsamplingScaleImageView ssiv = imageView.getSSIV();
|
||||
if (ssiv != null) {
|
||||
ssiv.setMaxScale(10f); // 这个缩放倍数最好很具宽高自动调节
|
||||
ssiv.setOnImageEventListener(new SubsamplingScaleImageView.DefaultOnImageEventListener() {
|
||||
@Override
|
||||
public void onReady() {
|
||||
ssiv.resetScaleAndCenter();
|
||||
}
|
||||
});
|
||||
ssiv.setOnClickListener(v -> finish());
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
loadImage(url, imageView);
|
||||
|
||||
//长按
|
||||
imageView.setOnLongClickListener(() -> {
|
||||
imageView.setOnLongClickListener(v -> {
|
||||
final Dialog dialog = new Dialog(ViewImageActivity.this);
|
||||
|
||||
LinearLayout container1 = new LinearLayout(ViewImageActivity.this);
|
||||
@ -353,8 +358,11 @@ public class ViewImageActivity extends BaseActivity implements OnPageChangeListe
|
||||
container1.setBackgroundColor(Color.WHITE);
|
||||
|
||||
final TextView reportTv = new TextView(ViewImageActivity.this);
|
||||
reportTv.setPadding(DisplayUtils.dip2px(ViewImageActivity.this, 20), DisplayUtils.dip2px(ViewImageActivity.this, 12),
|
||||
0, DisplayUtils.dip2px(ViewImageActivity.this, 12));
|
||||
reportTv.setPadding(
|
||||
DisplayUtils.dip2px(ViewImageActivity.this, 20),
|
||||
DisplayUtils.dip2px(ViewImageActivity.this, 12),
|
||||
0,
|
||||
DisplayUtils.dip2px(ViewImageActivity.this, 12));
|
||||
reportTv.setText(R.string.save_pic);
|
||||
reportTv.setTextSize(17);
|
||||
reportTv.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.title));
|
||||
@ -371,13 +379,15 @@ public class ViewImageActivity extends BaseActivity implements OnPageChangeListe
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
reportTv.setOnClickListener(v -> {
|
||||
reportTv.setOnClickListener(v1 -> {
|
||||
PermissionHelper.checkStoragePermissionBeforeAction(ViewImageActivity.this, () -> {
|
||||
findImageBM();
|
||||
saveImageToFile(imageView.getCurrentImageFile(), finalUrl);
|
||||
dialog.cancel();
|
||||
});
|
||||
dialog.cancel();
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
view.setTag(position);
|
||||
@ -385,100 +395,51 @@ public class ViewImageActivity extends BaseActivity implements OnPageChangeListe
|
||||
return view;
|
||||
}
|
||||
|
||||
private void findImageBM() {
|
||||
String url = urls.get(mViewPager.getCurrentItem());
|
||||
String limitUrl = ImageUtils.addLimitWidth(urls.get(mViewPager.getCurrentItem()), mLimitWidth);
|
||||
String targetUrl;
|
||||
|
||||
if (mImagePipeline.isInBitmapMemoryCache(ImageRequest.fromUri(url))) {
|
||||
targetUrl = url;
|
||||
} else if (mImagePipeline.isInBitmapMemoryCache(ImageRequest.fromUri(limitUrl))) {
|
||||
targetUrl = limitUrl;
|
||||
} else {
|
||||
targetUrl = url;
|
||||
}
|
||||
|
||||
|
||||
ImageRequest imageRequest = ImageRequestBuilder
|
||||
.newBuilderWithSource(Uri.parse(targetUrl))
|
||||
.setProgressiveRenderingEnabled(true)
|
||||
.build();
|
||||
|
||||
DataSource<CloseableReference<CloseableImage>>
|
||||
dataSource = mImagePipeline.fetchDecodedImage(imageRequest, ViewImageActivity.this);
|
||||
final String finalCurUrl = targetUrl;
|
||||
dataSource.subscribe(new BaseBitmapDataSubscriber() {
|
||||
@Override
|
||||
protected void onNewResultImpl(Bitmap bitmap) {
|
||||
if (bitmap != null) { // gif bitmap is null
|
||||
saveImage(bitmap, finalCurUrl);
|
||||
} else {
|
||||
ImageRequest imageRequest = ImageRequest.fromUri(Uri.parse(finalCurUrl));
|
||||
CacheKey encodedCacheKey = mImagePipeline.getCacheKeyFactory().getEncodedCacheKey(imageRequest, null);
|
||||
BinaryResource resource = Fresco.getImagePipelineFactory().getMainFileCache().getResource(encodedCacheKey);
|
||||
try {
|
||||
String fileName = finalCurUrl.substring(finalCurUrl.lastIndexOf("/"));
|
||||
String savePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/ghzhushou/";
|
||||
|
||||
File targetFile = new File(savePath, fileName);
|
||||
OutputStream outStream = new FileOutputStream(targetFile);
|
||||
outStream.write(resource.read());
|
||||
Utils.toast(ViewImageActivity.this, "图片已保存到/Pictures/ghzhushou/");
|
||||
MessageShareUtils.refreshImage(ViewImageActivity.this, targetFile);
|
||||
} catch (Exception e) {
|
||||
Utils.log("图片保存失败:" + e.toString());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFailureImpl(DataSource<CloseableReference<CloseableImage>> dataSource) {
|
||||
|
||||
}
|
||||
}, CallerThreadExecutor.getInstance());
|
||||
}
|
||||
|
||||
private void saveImage(Bitmap bitmap, String curUrl) {
|
||||
|
||||
String fileName = "";
|
||||
|
||||
if (mShowBase64Image) {
|
||||
fileName = MD5Utils.getUrlMD5(curUrl.substring(0, 50)) + ".png";
|
||||
} else {
|
||||
fileName = curUrl.substring(curUrl.lastIndexOf("/"));
|
||||
}
|
||||
|
||||
String savePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/ghzhushou/";
|
||||
|
||||
private void saveImageToFile(File src, String curUrl) {
|
||||
InputStream in = null;
|
||||
OutputStream out = null;
|
||||
try {
|
||||
String fileName;
|
||||
if (mShowBase64Image) {
|
||||
fileName = MD5Utils.getUrlMD5(curUrl.substring(0, 50)) + ".png";
|
||||
} else {
|
||||
fileName = curUrl.substring(curUrl.lastIndexOf("/"));
|
||||
}
|
||||
String savePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/ghzhushou/";
|
||||
File file = new File(savePath);
|
||||
if (!file.exists()) {
|
||||
file.mkdirs();
|
||||
}
|
||||
|
||||
File f = new File(savePath, fileName);
|
||||
if (f.exists()) {
|
||||
f.delete();
|
||||
File dst = new File(savePath, fileName);
|
||||
if (dst.exists()) {
|
||||
dst.delete();
|
||||
}
|
||||
|
||||
in = new FileInputStream(src);
|
||||
out = new FileOutputStream(dst);
|
||||
byte[] buf = new byte[1024];
|
||||
int len;
|
||||
while ((len = in.read(buf)) > 0) {
|
||||
out.write(buf, 0, len);
|
||||
}
|
||||
|
||||
FileOutputStream out = new FileOutputStream(f);
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
|
||||
out.flush();
|
||||
out.close();
|
||||
Utils.log("图片保存成功");
|
||||
Utils.toast(ViewImageActivity.this, "图片已保存到/Pictures/ghzhushou/");
|
||||
MessageShareUtils.refreshImage(ViewImageActivity.this, f);
|
||||
} catch (IOException e) {
|
||||
} catch (Exception e) {
|
||||
Utils.log("图片保存失败:" + e.toString());
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (out != null) out.close();
|
||||
if (in != null) in.close();
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
|
||||
container.removeView((View) object);
|
||||
object = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user