android ViewPager 图片浏览和保存图片

本文介绍了一个用于浏览多张图片的Android Activity实现方案。通过ViewPager展示图片,并使用Glide进行图片加载,支持图片保存到本地的功能。

在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.ViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <ImageView
        android: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" />

    <TextView
        android: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" />

    <TextView
        android: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"
       />

    <TextView
        android: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" />

    <ImageView
        android: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;

    @Override
    protected 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() {
            @Override
            public int getCount() {
                return imageUrls.length;
            }


            @Override
            public boolean isViewFromObject(View view, Object object) {
                return view == object;
            }

            @Override
            public 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>() {
                        @Override
                        public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
                            if (position == curPosition) {
                                hideLoadingAnimation();
                            }
                            showErrorLoading();
                            return false;
                        }

                        @Override
                        public 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() {
                        @Override
                        public void onClick(View v) {
                            finish();
                        }
                    });
                    view.setTag(position);
                    container.addView(view);
                    return view;
                }
                return null;
            }


            @Override
            public 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() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                if (initialedPositions[position] != position) {//如果当前页面未加载完毕,则显示加载动画,反之相反;
                    showLoadingAnimation();
                } else {
                    hideLoadingAnimation();
                }
                curPosition = position;
                curImageUrl = imageUrls[position];
                photoOrderTv.setText((position + 1) + "/" + imageUrls.length);//设置页面的编号
            }

            @Override
            public 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;
    }

    @Override
    public 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_375x225
        return url.contains("yxtribe") ? url.split("-style")[0] : url;
    }

    private void saveOriginalPhotoToLocal(final String url) {
        new Thread(new Runnable() {
            @Override
            public 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() {
                            @Override
                            public void onSavedSuccess() {
                                runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        Toast.makeText(PhotoBrowserActivity.this, "已保存至相册", Toast.LENGTH_SHORT).show();
                                    }
                                });
                            }

                            @Override
                            public void onSavedFailed() {
                                runOnUiThread(new Runnable() {
                                    @Override
                                    public 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() {
                    @Override
                    public void onSavedSuccess() {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(PhotoBrowserActivity.this, "已保存至相册", Toast.LENGTH_SHORT).show();
                            }
                        });
                    }

                    @Override
                    public void onSavedFailed() {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(PhotoBrowserActivity.this, "保存失败", Toast.LENGTH_SHORT).show();
                            }
                        });
                    }
                });
            }
        } catch (Exception e) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(PhotoBrowserActivity.this, "保存失败", Toast.LENGTH_SHORT).show();
                }
            });
        }
    }

    @Override
    protected 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() {
            @Override
            public 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

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值