利用Glide、PhotoView、Dialog、ViewPager实现图片加载和查看

简介

  • 对图片的加载和查看做了一个简单的封装,其目的是为了提高复用性,让主类变的更简洁,只需“三行代码”即可实现图片的加载预览以及查看。
showImagesAndEnlargement = new ShowImagesAndEnlargement(this , imageUrls , imageGroup);
//加载到指定预览的View上
showImagesAndEnlargement.showImages();
//点击预览图片进行放大查看,PhotoView可对图片放大缩小
//这行代码是放在指定预览View的监听上
showImagesAndEnlargement.showDialogImages();

原理

  • 1.首先用Glide将图片加载到指定View,用于开始的预览。它可以从多个源加载图片,如:网路,本地,Uri等,并且采用三级缓存策略。
  • 2.自定义Dialog,尺寸设置全屏(利用Display的getMetricsgetMetrics(DisplayMetrics outMetrics)方法来获取屏幕尺寸)。
  • 3.新建一个Layout,添加ViewPager,其目的是为了实现多张图片情况下的左右滑动。
  • 4.动态创建PhotoView,layoutParams的宽高设置为MATCH_PARENT。它可对图片能进行一个放大和缩小。
    注:PhotoView的数量是根据url的数量来决定的,以及再次用Glide将图片加载到PhotoView上,总共是进行了两次加载(指定View和PhotoView)。注意不能等到点击图片后才给PhotoView上加载图片,一定要提前加载,不然会出现图片加载的一个等待过程,以及去掉Glide中的placeholder占位图,因为不管你有没有提前加载它都会出现。(以上这段话不理解没事er,可以先略过)
  • 5.利用适配器将PhotoView放到ViewPager中。
  • 6.最后一步就是将Viewpager Set到Dialog当中

添加依赖

  //图片加载库
  implementation 'com.github.bumptech.glide:glide:4.10.0'
  annotationProcessor 'com.github.bumptech.glide:compiler:4.0.0'
  //图片查看库
  implementation 'com.github.chrisbanes:PhotoView:2.3.0'

加载图片的Utils

  • 这只是一个图片的加载工具类(附属类),没有去和查看图片集成到一块,你可以根据自己的需求做以改动。这个类包含两个方法,一个是加载到指定预览的View上,一个是加载到PhotoView上,其实可以用一个方法来实现,就是把接收View的集合改成泛型,但是这样显示不清晰合理,并且太麻烦,所以就没有用泛型来接。
package com.example.attendance.util;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.widget.ImageView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestBuilder;
import com.bumptech.glide.request.RequestOptions;
import com.example.attendance.R;
import com.github.chrisbanes.photoview.PhotoView;

import java.util.List;

/**
 * @ClassName LoadImageUtils
 * @Description 图片加载工具
 * @Author YiYaKim
 * @Date 2020/3/3 18:02
 * @Version 1.0
 */


public class LoadImageUtils {

    /**
     * @Description 加载多张图片
     * @param imageGroup imageView
     * @param imageUrls url
     */
    @SuppressLint("CheckResult")
    public static void multipleLoadImageView(Context context , List<ImageView> imageGroup , List<String> imageUrls){
        RequestOptions options = new RequestOptions();
        options.centerCrop()
                .placeholder(R.drawable.default_avatar)
                .error(R.drawable.image_error)
                .fallback(R.drawable.image_error)
                .fitCenter();
        RequestBuilder<Drawable> requestBuilder =
                Glide.with(context)
                        .asDrawable()
                        .apply(options)
                ;
        for(int i = 0 ; i < imageUrls.size() ; i++){
            ImageView view = imageGroup.get(i);
            requestBuilder.clone()
                    .load(imageUrls.get(i))
                    .into(view);
        }
    }

    @SuppressLint("CheckResult")
    public static void multipleLoadPhotoView(Context context , List<PhotoView> imageGroup , List<String> imageUrls){
        RequestOptions options = new RequestOptions();
        options.centerCrop()
                .error(R.drawable.image_error)
                .fallback(R.drawable.image_error)
                .fitCenter();  //图片填充
        RequestBuilder<Drawable> requestBuilder =
                Glide.with(context)
                        .asDrawable().apply(options);
        for(int i = 0 ; i < imageUrls.size() ; i++){
            PhotoView view = imageGroup.get(i);
            requestBuilder.clone()
                    .load(imageUrls.get(i))
                    .into(view);
        }
    }
}

自定义Dialog

  • 主要做了Dialog显示大小的设置,以及将ViewPager Set到Dialog上去。里面还加了一个Title,就是为了显示图片的个数,可以根据自己需求来决定。(ViewPager是我自定义的{@link ShowImagesViewPager},你可以自行替换)
package com.example.attendance.photoview;

import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.viewpager.widget.ViewPager;
import com.example.attendance.R;
import com.example.attendance.common.Constants;
import com.github.chrisbanes.photoview.PhotoView;

import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName ShowImagesDialog
 * @Description 嵌套了viewpager的图片浏览
 * @Author YiYaKim
 * @Date 2020/3/3 18:22
 * @Version 1.0
 */

public class ShowImagesDialog extends Dialog {
    private View mView ;
    private Context mContext;
    private ShowImagesViewPager mViewPager;
    private TextView mIndexText;
    private List<PhotoView> photoViews;
    private List<String> mTitles;
    private List<View> mViews;
    private ShowImagesAdapter mAdapter;

    public ShowImagesDialog(@NonNull Context context, List<PhotoView> photoViews) {
        super(context, R.style.transparentBgDialog);
        this.mContext = context;
        this.photoViews = photoViews;
        initView();
        initData();
    }

    private void initView() {
        mView = View.inflate(mContext, R.layout.dialog_images_brower, null);
        mViewPager = mView.findViewById(R.id.vp_images);
        mIndexText = mView.findViewById(R.id.tv_image_index);
        mTitles = new ArrayList<>();
        mViews = new ArrayList<>();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(mView);
        Window window = getWindow();
        WindowManager.LayoutParams wl = window.getAttributes();
        wl.x = 0;
        wl.y = 0;
        wl.height = Constants.EXACT_SCREEN_HEIGHT ;
        wl.width = Constants.EXACT_SCREEN_WIDTH ;
        wl.gravity = Gravity.CENTER;
        window.setAttributes(wl);
    }
    @SuppressLint("SetTextI18n")
    private void initData() {
        for (int i = 0; i < photoViews.size(); i++) {
            mViews.add(photoViews.get(i));
            mTitles.add(i + "");
        }

        mAdapter = new ShowImagesAdapter(mViews, mTitles);
        mViewPager.setAdapter(mAdapter);
        mIndexText.setText(1 + "/" + photoViews.size());
        mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                mIndexText.setText(position + 1 + "/" + photoViews.size());
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
    }


    public void setCurrentViewPage(int item){
        mViewPager.setCurrentItem(item);
    }

}

适配器

package com.example.attendance.photoview;

import android.view.View;
import android.view.ViewGroup;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;

import java.util.List;

/**
 * @ClassName ShowImagesAdapter
 * @Description TODO
 * @Author YiYaKim
 * @Date 2020/3/3 18:30
 * @Version 1.0
 */

public class ShowImagesAdapter extends PagerAdapter {

    private List<View> views;
    private List<String> titles;

    public ShowImagesAdapter(List<View> views, List<String> titles) {
        this.views = views;
        this.titles = titles;
    }

    @Override
    public boolean isViewFromObject(View arg0, Object arg1) {
        return arg0 == arg1;
    }

    @Override
    public int getCount() {
        return views.size();
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        ((ViewPager) container).removeView(views.get(position));
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {

        ((ViewPager) container).addView(views.get(position));
        return views.get(position);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return titles == null ? "" : titles.get(position);
    }
}

核心类

  • 该类融合了加载和查看,在主类使用该类调用相关方法即可实现图片的加载和查看。
package com.example.attendance.util;

import android.content.Context;
import android.view.ViewGroup;
import android.widget.ImageView;
import com.example.attendance.photoview.ShowImagesDialog;
import com.github.chrisbanes.photoview.OnPhotoTapListener;
import com.github.chrisbanes.photoview.PhotoView;

import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName ShowImagesAndEnlargement
 * @Description 显示照片和放大查看以及缩放 {@link com.bumptech.glide.Glide} {@link PhotoView}
 * @Author YiYaKim
 * @Date 2020/3/4 15:20
 * @Version 1.0
 */
public class ShowImagesAndEnlargement {
    private Context context;
    private List<ImageView> imageGroup;
    private ShowImagesDialog showImagesDialog;
    private List<PhotoView> imagesDialogs = new ArrayList<>();
    //不管是多张还是一张,加载图片根据的是imageUrls的数量不是根据imageGroup,因为View是去匹配URL的数量
    private List<String> imageUrls;

    public ShowImagesAndEnlargement(Context context , List<String> imageUrls , List<ImageView> imageGroup){
        this.context = context;
        this.imageUrls = imageUrls;
        this.imageGroup = imageGroup;
    }

    /**
     * 显示照片 {@link com.bumptech.glide.Glide}
     */
    public void showImages() {
        LoadImageUtils.multipleLoadImageView(context , imageGroup , imageUrls);
        enlargement(imageUrls);
        showImagesDialog = new ShowImagesDialog(context , imagesDialogs);
    }

    /**
     * 为Dialog做准备,提前把图片加载到PhotoView上  {@link PhotoView}
     * @param imageUrls 图片的url
     */
    private void enlargement(List<String> imageUrls) {
        for (int i = 0; i < imageUrls.size(); i++) {
            PhotoView photoView = new PhotoView(context);
            ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
            photoView.setLayoutParams(layoutParams);
            photoView.setOnPhotoTapListener(new OnPhotoTapListener() {
                @Override
                public void onPhotoTap(ImageView view, float x, float y) {
                    //因为showImagesDialog是全局变量,并且在点击的时候已经有了实例
                    if(showImagesDialog != null){
                        showImagesDialog.dismiss();
                    }
                }
            });
            imagesDialogs.add(photoView);
        }
        //将图片加载到PhotoView上
        LoadImageUtils.multipleLoadPhotoView(context , imagesDialogs, imageUrls);
    }

    /**
     * 显示PhotoView
     */
    public void showDialogImages(){
        showImagesDialog.show();
    }

    /**
     * 显示指定页面
     * @param item 某一页面
     */
    public void setCurrentViewPage(int item){
        showImagesDialog.setCurrentViewPage(item);
    }
}

  • End~~~结束啦!!!
    以前都是从简书上来搬运别人的代码,自己从来在简书上没写过,这次就本着取之于民用之于民的道理终于自己写一次啦!这样利己又利人何乐而不为呢,因为在写的时候也是对自己所掌握知识的一个巩固,并且孔子说过,教人是最好的学习方法。其实分享对我来说也是一种快乐,陶醉于其中,哈哈哈哈~~~~~~
    对了,有不足或者错误的地方还望各位小伙伴指出,共同探讨哦!!!
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 227,401评论 6 531
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 98,011评论 3 413
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 175,263评论 0 373
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 62,543评论 1 307
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 71,323评论 6 404
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 54,874评论 1 321
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 42,968评论 3 439
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 42,095评论 0 286
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 48,605评论 1 331
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 40,551评论 3 354
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 42,720评论 1 369
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 38,242评论 5 355
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 43,961评论 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 34,358评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 35,612评论 1 280
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 51,330评论 3 390
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 47,690评论 2 370

推荐阅读更多精彩内容