在build.gradle在添加依赖
compile 'com.alibaba:fastjson:1.1.54.android'
compile 'org.ligboy.retrofit2:converter-fastjson-android:2.1.0'compile 'com.bm.photoview:library:1.4.1'
compile 'xiaofei.library:android-data-storage:1.3.0'
在layout下创建activity_photo_browser.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@color/black"><android.support.v4.view.ViewPagerandroid:id="@+id/pager"android:layout_width="match_parent"android:layout_height="match_parent" /><ImageViewandroid:id="@+id/crossIv"android:layout_width="24dp"android:layout_height="24dp"android:layout_marginLeft="@dimen/activity_horizontal_margin"android:layout_marginTop="@dimen/activity_horizontal_margin"android:visibility="gone"android:src="@drawable/rp_closed_icon" /><TextViewandroid:id="@+id/photoOrderTv"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="bottom|left"android:layout_margin="@dimen/activity_horizontal_margin"android:padding="10dp"android:textSize="14sp"android:textColor="@color/white" /><TextViewandroid:id="@+id/downloadOriginal"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="bottom|center"android:visibility="gone"android:layout_margin="@dimen/activity_horizontal_margin"android:padding="10dp"android:textSize="10sp"android:text="下载原图"android:textColor="@color/white"/><TextViewandroid:id="@+id/saveTv"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="bottom|right"android:layout_margin="@dimen/activity_horizontal_margin"android:padding="10dp"android:textSize="14sp"android:visibility="visible"android:text="保存"android:textColor="@color/white" /><ImageViewandroid:layout_width="32dp"android:layout_height="32dp"android:src="@drawable/loading"android:layout_gravity="center"android:visibility="gone"android:id="@+id/centerIv"/></FrameLayout>
创建浏览图片的activity
/*** ProjectName: zhenhua* Author: lgq* Date: 2017/12/19 0019 15:29*/
public class PhotoBrowserActivity extends Activity implements View.OnClickListener {private ImageView crossIv;private ViewPager mPager;private ImageView centerIv;private TextView photoOrderTv;private TextView downloadOriginalTv;private TextView saveTv;private String curImageUrl = "";private String[] imageUrls = new String[]{};private int curPosition = -1;private int[] initialedPositions = null;private ObjectAnimator objectAnimator;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);setContentView(R.layout.activity_photo_browser);String urls = getIntent().getStringExtra("imageUrls");JSONArray urlsJsonArray = JSONArray.parseArray(urls);imageUrls = urlsJsonArray.toArray(new String[urlsJsonArray.size()]);for (int i = 0; i < imageUrls.length; i++) {imageUrls[i] = getOriginalUrl(imageUrls[i]);}curImageUrl = getIntent().getStringExtra("curImageUrl");initialedPositions = new int[imageUrls.length];initInitialedPositions();photoOrderTv = (TextView) findViewById(R.id.photoOrderTv);downloadOriginalTv = (TextView) findViewById(R.id.downloadOriginal);downloadOriginalTv.setOnClickListener(this);saveTv = (TextView) findViewById(R.id.saveTv);saveTv.setOnClickListener(this);centerIv = (ImageView) findViewById(R.id.centerIv);crossIv = (ImageView) findViewById(R.id.crossIv);crossIv.setOnClickListener(this);mPager = (ViewPager) findViewById(R.id.pager);mPager.setPageMargin((int) (getResources().getDisplayMetrics().density * 15));mPager.setAdapter(new PagerAdapter() {@Overridepublic int getCount() {return imageUrls.length;}@Overridepublic boolean isViewFromObject(View view, Object object) {return view == object;}@Overridepublic Object instantiateItem(ViewGroup container, final int position) {if (imageUrls[position] != null && !"".equals(imageUrls[position])) {final PhotoView view = new PhotoView(PhotoBrowserActivity.this);view.enable();view.setScaleType(ImageView.ScaleType.FIT_CENTER);Glide.with(PhotoBrowserActivity.this).load(imageUrls[position]).override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL).fitCenter().crossFade().listener(new RequestListener<String, GlideDrawable>() {@Overridepublic boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {if (position == curPosition) {hideLoadingAnimation();}showErrorLoading();return false;}@Overridepublic boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {occupyOnePosition(position);if (position == curPosition) {hideLoadingAnimation();}return false;}}).into(view);view.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {finish();}});view.setTag(position);container.addView(view);return view;}return null;}@Overridepublic void destroyItem(ViewGroup container, int position, Object object) {releaseOnePosition(position);container.removeView((View) object);}});curPosition = returnClickedPosition() == -1 ? 0 : returnClickedPosition();mPager.setCurrentItem(curPosition);
// mPager.setTag(curPosition);if (initialedPositions[curPosition] != curPosition) {//如果当前页面未加载完毕,则显示加载动画,反之相反;showLoadingAnimation();}photoOrderTv.setText((curPosition + 1) + "/" + imageUrls.length);//设置页面的编号mPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {@Overridepublic void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}@Overridepublic void onPageSelected(int position) {if (initialedPositions[position] != position) {//如果当前页面未加载完毕,则显示加载动画,反之相反;showLoadingAnimation();} else {hideLoadingAnimation();}curPosition = position;curImageUrl = imageUrls[position];photoOrderTv.setText((position + 1) + "/" + imageUrls.length);//设置页面的编号}@Overridepublic void onPageScrollStateChanged(int state) {}});}private int returnClickedPosition() {if (imageUrls == null || curImageUrl == null) {return -1;}for (int i = 0; i < imageUrls.length; i++) {if (getOriginalUrl(curImageUrl).equals(imageUrls[i])) {return i;}}return -1;}@Overridepublic void onClick(View view) {switch (view.getId()) {case R.id.crossIv:finish();break;case R.id.saveTv:
// savePhotoToLocal();saveOriginalPhotoToLocal(getOriginalUrl(curImageUrl));break;case R.id.downloadOriginal:saveOriginalPhotoToLocal(getOriginalUrl(curImageUrl));break;default:break;}}private void showLoadingAnimation() {centerIv.setVisibility(View.VISIBLE);centerIv.setImageResource(R.drawable.loading);if (objectAnimator == null) {objectAnimator = ObjectAnimator.ofFloat(centerIv, "rotation", 0f, 360f);objectAnimator.setDuration(2000);objectAnimator.setRepeatCount(ValueAnimator.INFINITE);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {objectAnimator.setAutoCancel(true);}}objectAnimator.start();}private void hideLoadingAnimation() {releaseResource();centerIv.setVisibility(View.GONE);}private void showErrorLoading() {releaseResource();centerIv.setRotation(0f);centerIv.setVisibility(View.GONE);centerIv.setImageResource(R.drawable.list_img);}private void releaseResource() {if (objectAnimator != null) {objectAnimator.cancel();}if (centerIv.getAnimation() != null) {centerIv.getAnimation().cancel();}}private void occupyOnePosition(int position) {initialedPositions[position] = position;}private void releaseOnePosition(int position) {initialedPositions[position] = -1;}private void initInitialedPositions() {for (int i = 0; i < initialedPositions.length; i++) {initialedPositions[i] = -1;}}private String getOriginalUrl(String url) {//http://images.yxtribe.com/upload/images/ep123456/20171101184127659.jpg-style_webp_375x225return url.contains("yxtribe") ? url.split("-style")[0] : url;}private void saveOriginalPhotoToLocal(final String url) {new Thread(new Runnable() {@Overridepublic void run() {Bitmap bitmap = null;try {
// file = Glide.with(context)
// .load(url)
// .downloadOnly(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
// .get();bitmap = Glide.with(PhotoBrowserActivity.this).load(url).asBitmap().into(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL).get();if (bitmap != null){// 在这里执行图片保存方法Utils.savePhoto(PhotoBrowserActivity.this, bitmap, new Utils.SaveResultCallback() {@Overridepublic void onSavedSuccess() {runOnUiThread(new Runnable() {@Overridepublic void run() {Toast.makeText(PhotoBrowserActivity.this, "已保存至相册", Toast.LENGTH_SHORT).show();}});}@Overridepublic void onSavedFailed() {runOnUiThread(new Runnable() {@Overridepublic void run() {Toast.makeText(PhotoBrowserActivity.this, "保存失败", Toast.LENGTH_SHORT).show();}});}});}} catch (Exception e) {e.printStackTrace();}}}).start();}private void savePhotoToLocal() {try {// ViewGroup containerTemp = (ViewGroup) mPager.findViewWithTag(mPager.getCurrentItem());
// if (containerTemp == null) {
// return;
// }
// PhotoView photoViewTemp = (PhotoView) mPager.getChildAt(curPosition);
// ViewGroup containerTemp = (ViewGroup) mPager.findViewWithTag(mPager.getCurrentItem());
// if (containerTemp == null) {
// return;
// }PhotoView photoViewTemp = (PhotoView) mPager.findViewWithTag(mPager.getCurrentItem());if (photoViewTemp != null) {GlideBitmapDrawable glideBitmapDrawable = (GlideBitmapDrawable) photoViewTemp.getDrawable();if (glideBitmapDrawable == null) {return;}Bitmap bitmap = glideBitmapDrawable.getBitmap();if (bitmap == null) {return;}Utils.savePhoto(this, bitmap, new Utils.SaveResultCallback() {@Overridepublic void onSavedSuccess() {runOnUiThread(new Runnable() {@Overridepublic void run() {Toast.makeText(PhotoBrowserActivity.this, "已保存至相册", Toast.LENGTH_SHORT).show();}});}@Overridepublic void onSavedFailed() {runOnUiThread(new Runnable() {@Overridepublic void run() {Toast.makeText(PhotoBrowserActivity.this, "保存失败", Toast.LENGTH_SHORT).show();}});}});}} catch (Exception e) {runOnUiThread(new Runnable() {@Overridepublic void run() {Toast.makeText(PhotoBrowserActivity.this, "保存失败", Toast.LENGTH_SHORT).show();}});}}@Overrideprotected void onDestroy() {releaseResource();if (mPager != null) {mPager.removeAllViews();mPager = null;}super.onDestroy();}
}
Utils类
public class Utils {public interface SaveResultCallback {void onSavedSuccess();void onSavedFailed();}public static File getSDPath() {File sdDir = null;boolean sdCardExist = Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED); //判断sd卡是否存在if (sdCardExist) {sdDir = Environment.getExternalStorageDirectory();//获取跟目录}return sdDir;}public static void savePhoto(final Context context, final Bitmap bmp, final SaveResultCallback saveResultCallback) {final File sdDir = getSDPath();if (sdDir == null) {Toast.makeText(context,"设备自带的存储不可用",Toast.LENGTH_LONG).show();return;}new Thread(new Runnable() {@Overridepublic void run() {File appDir = new File(sdDir, "out_photo");if (!appDir.exists()) {appDir.mkdir();}SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");//设置以当前时间格式为图片名称String fileName = df.format(new Date()) + ".png";File file = new File(appDir, fileName);try {FileOutputStream fos = new FileOutputStream(file);bmp.compress(Bitmap.CompressFormat.PNG, 100, fos);fos.flush();fos.close();saveResultCallback.onSavedSuccess();} catch (FileNotFoundException e) {saveResultCallback.onSavedFailed();e.printStackTrace();} catch (IOException e) {saveResultCallback.onSavedFailed();e.printStackTrace();}//保存图片后发送广播通知更新数据库Uri uri = Uri.fromFile(file);context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri));}}).start();}
}
启动图片浏览activity
Intent intent = new Intent();intent.putExtra("imageUrls", "[\"http://images.yxtribe.com/upload/images/business/20171017094330268.jpg-style_webp_750x350\",\"http://images.yxtribe.com/upload/images/business/330/20170812092209128.PNG-style_webp_375x225\",\"http://images.yxtribe.com/upload/images/business/330/20170812092227983.PNG-style_webp_375x225\",\"http://images.yxtribe.com/upload/images/business/330/20170812092239697.PNG-style_webp_375x225\",\"http://images.yxtribe.com/upload/images/business/330/20170812092244210.PNG-style_webp_375x225\",\"http://images.yxtribe.com/upload/images/business/330/20170812092246121.PNG-style_webp_375x225\",\"http://images.yxtribe.com/upload/images/business/330/20170812092249515.PNG-style_webp_375x225\"]");intent.putExtra("curImageUrl", "http://images.yxtribe.com/upload/images/business/20171017094330268.jpg-style_webp_750x350");
// Log.v("lgq","tophoto===== "+img+"..... "+ imageUrls);intent.setClass(OneActivity.this, PhotoBrowserActivity.class);startActivity(intent);
//imageUrls格式可变 同时app需要网络链接权限
改进版:https://blog.csdn.net/meixi_android/article/details/82801273