Android图片浏览模式以及图片保存的实现

在访问微信朋友圈的时候,点击里面的图片可以进行多图浏览,手势缩放,以及图片保存的功能,正好项目里也有这样一个需求,并且顺利完成了,现在拿出来和大家分享一下。

图片浏览模式的实现大体流程如下:

第一步:弹出popupWindow
第二步:popupWindow中创建保存按钮和viewpager对象
第三步:为viewpager添加视图
第四步:图片支持缩放
第五步:获取图片并保存

第一步:
首先在点击图片时会弹出popupWindow,当然要得到图片位置和图片列表数据,这个图片列表数据里的对象可以是bitmap,图片地址,byte字节等;
    PopupWindow popupWindow;
    /**记录viewpager滑动到的位置*/
    private int currentPosition;
    protected List<RelativeLayout> imageList = new ArrayList<>();
     /**
     * 弹出展示图片框
     */
    private void showImagePopup(List<String> list, int position) {
        currentPosition = position;
        imageList.clear();
      /**
       * popupWindow对象充满屏幕
       */
        popupWindow = new PopupWindow(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        /**手机版本较低时popupWindow会充满整个屏幕,包括状态栏*/
        if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT){
            popupWindow.setHeight(DipUtils.getScreenHeight(this) - StatusBarCompat.getStatusBarHeight(this));
        }
        View contentView = LayoutInflater.from(this).inflate(R.layout.popup_window_big_image, null);
        TextView save = (TextView) contentView.findViewById(R.id.tv_save);
        final ViewPager viewPager = (ViewPager) contentView.findViewById(R.id.popup_vp);

        /**为viewpager创建适配*/
        setViewPagerAdapter(viewPager, list);
        /**position为当前正在被点击的图片的位置,展示正被点击的图片*/
        viewPager.setCurrentItem(position);
        viewPager.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (popupWindow != null && popupWindow.isShowing()) {
                    popupWindow.dismiss();
                }
            }
        });
        save.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showProgressDialog("正在保存...");
                saveImage();
            }
        });
        /**如果想要点击back键时弹框消失,这两个属性必须使用并同时使用*/
        popupWindow.setBackgroundDrawable(new ColorDrawable());
        popupWindow.setFocusable(true);
        popupWindow.setContentView(contentView);
        popupWindow.setOutsideTouchable(true);

        popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
            @Override
            public void onDismiss() {

            }
        });
        /**设置入场出场动画,可以不设置*/
        popupWindow.setAnimationStyle(R.style.PopupImageScale);
        /**popupWindow底部展示,参数一可以传入当前界面初始化了的任意的一个view对象*/
        popupWindow.showAtLocation(mToolBar, Gravity.BOTTOM, 0, 0);
    }

popupWindow的contentView布局文件代码如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/text_color"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv_save"
        android:layout_width="wrap_content"
        android:layout_height="45dp"
        android:layout_alignParentRight="true"
        android:paddingLeft="16dp"
        android:paddingRight="26dp"
        android:text="保存"
        android:gravity="center"
        android:textSize="16sp"
        android:textColor="@color/white"/>

    <android.support.v4.view.ViewPager
        android:id="@+id/popup_vp"
        android:layout_below="@id/tv_save"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</RelativeLayout>

以上是创建popupWindow的步骤,基本操作啦~,这些想必大家都会,并且还可以把代码写的更简洁。

第二步:
创建完popupWindow之后,要对viewpager进行视图填充,在完成这一步时,因为只是简单的图片视图,所以就没有重新写新的布局文件,具体代码如下:
     /**
     * 设置点击放大图片适配器
     */
    private void setViewPagerAdapter(ViewPager viewPager, List<String> list) {
        for (int i = 0; i < list.size(); i++) {
            imageList.add(getView(list.get(i)));
        }
        viewPager.setAdapter(new PagerAdapter() {
            @Override
            public int getCount() {
                return imageList.size();
            }

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

            }

            @Override
            public Object instantiateItem(ViewGroup container, int position) {
                container.addView(imageList.get(position));
                return imageList.get(position);
            }

            @Override
            public void destroyItem(ViewGroup container, int position, Object object) {
                container.removeView(imageList.get(position));
            }
        });
        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                currentPosition = position;
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
    }

在viewpager中添加view对象或者是fragment,但是添加fragment会报错,在这里提一下,popupWindow中不能添加fragment对象,网上的解决方法是将popupWindow换成DialogFragment,大家可以根据兴趣自行研究。

第三步:
为viewpager天剑视图,代码如下:
 /**
     * 获取图片及图片布局
     */
    private RelativeLayout getView(String s) {
    /**由于图片要居中显示,所以选择父布局为相对布局,为什么要为图片外面嵌套一层父布局,下面会进行讲解*/
        final RelativeLayout view = new RelativeLayout(this);
        ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams
                (ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        view.setLayoutParams(layoutParams);
        /**PhotoView是ImageView的子类*/
        PhotoView imageView = new PhotoView(this);
        RelativeLayout.LayoutParams layoutParams1 = new RelativeLayout.LayoutParams
                (ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        /**设置布局规则*/        
        layoutParams1.addRule(RelativeLayout.CENTER_IN_PARENT);
        imageView.setLayoutParams(layoutParams1);
        view.addView(imageView);
        Glide.with(this).load(s).into(imageView);
        view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (popupWindow != null && popupWindow.isShowing())
                    popupWindow.dismiss();
            }
        });
        return view;
    }

上面的代码中为图片添加父布局,是为了让图片自适应宽高,然后为图片设置规则,为居中显示,当然还可以设置其他属性,如果没有这一层父布局嵌套,那么图片会充满屏幕;

第四步:
图片缩放功能的实现,可以使用上面用到的PhotoView, GitHub地址点这里,这是一个安全的开源控件,我使用的版本是2.1.3,已经有一万二的star了,使用起来也很简单。
第五步:
保存图片:
我们所做的项目中加载图片一般会用到图片加载框架,Glide或者Picasso,后台返回给我们的图片数据一般是一个图片地址,使用glide加载完成后可以通过如下方法获取到图片对象:
Glide.with(this).load(s).asBitmap().into(new ImageViewTarget<Bitmap>(imageView) {
            @Override
            protected void setResource(Bitmap resource) {

            }
        });

resource即是bitmap对象,但是获取到图片后要讲其保存起来,然后再在保存的时候取出来,这样就显得很繁琐,所以使用另外一种更加简单的方法来保存图片,不需要保存对象,也不需要去重新取值。

    /**
     * 保存图片到本地
     */
    private void saveImage() {
        if (imageList != null && imageList.size() != 0 && currentPosition < imageList.size()) {
            RelativeLayout view = imageList.get(currentPosition);
            ImageView iv = (ImageView) view.getChildAt(0);
            iv.setDrawingCacheEnabled(true);
            Bitmap bitmap = iv.getDrawingCache();
            if (BitmapUtil.saveImageToGallery(this, bitmap)) {
                hideProgressDialog();
                showToast("保存成功");
            } else {
                hideProgressDialog();
                showToast("保存失败");
            }
            iv.setDrawingCacheEnabled(false);
        } else {
            hideProgressDialog();
        }

    }

通过图片本身来进行保存,在获取对象之前要打开:
iv.setDrawingCacheEnabled(true);
在完成之后关闭:
iv.setDrawingCacheEnabled(false);

到这里,图片浏览模式和图片保存就完成了,如果有疑问,请给我留言,如果那里写的有问题,也请给我留言。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值