PhotoView+Glide+Dialog+ViewPager

作者: 大天使之剣 | 来源:发表于2017-05-04 23:07 被阅读3008次

    前言

    在接手老代码后发现的问题,近日在项目中发现用的图片浏览框架搭的是FragmentActivity+fragment+viewpager+photoview框架,运用fragment来仅仅装载一张图片(photoview同样也是继承imageview的)未免显得太过笨重

    其实不单单是做简单的图片浏览、android原生的dialog可以做到activity、fragment的大部分展示功能,而且更轻量化,易于封装与维护。

    本文旨在替换fragment浏览图片的笨重方案,图片控件为了支持手势,还是用github上的PhotoView,在使用中出现什么问题可以看一下参考文档,图片加载控件用的Google开源的Glide,Glide的好处我就不多说了。


    1.gradle配置

    dependencies {
        compile 'com.github.chrisbanes.photoview:library:+'
        compile 'com.github.bumptech.glide:glide:3.7.0'
    }
    

    2.dialog样式

    由于我们图片一般是全屏展示,而且用系统原本的style不同版本之间会有更加奇怪的现象(如自带边框与黑色背景的window)所以对话框的style需要自定义一下,大概意思就是全屏+window背景透明
    在values/styles下新增如下样式:

    <!--全屏背景半透明 dialog-->
        <style name="transparentBgDialog" parent="@android:style/Theme.Dialog">
            <item name="android:windowFrame">@null</item>
            <item name="android:windowIsFloating">true</item>
            <item name="android:windowIsTranslucent">true</item>
            <item name="android:windowBackground">@color/transparent</item>
            <item name="android:backgroundDimEnabled">true</item>
            <item name="android:background">@color/transparent</item>
            <item name="android:windowNoTitle">true</item>
        </style>
    

    3.ShowImagesDialog的创建

    毫无疑问的我们继承一下Dialog类并在构造方法里更改style样式并拿到图片url地址list。为了在系统创建dialog时能够全屏展示我们的图片以及其他更多的界面信息(如索引),在系统创建dialog时指定大小为屏幕宽高。

      public ShowImagesDialog(@NonNull Context context, List<String> imgUrls) {
            super(context, R.style.transparentBgDialog);
            ···
      }
        @Override
      protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            requestWindowFeature(Window.FEATURE_NO_TITLE);
            this.setContentView(mView);
            Window window = getWindow();
            WindowManager.LayoutParams wl = window.getAttributes();
            wl.x = 0;
            wl.y = 0;
            wl.height = Config.EXACT_SCREEN_HEIGHT;
            wl.width = Config.EXACT_SCREEN_WIDTH; //屏幕宽高的属性由DisplayMetrics类获得
            wl.gravity = Gravity.CENTER;
            window.setAttributes(wl);
      }
    

    4.xml布局

    布局很简单,就一个图片文字索引跟photoview的父控件viewpager

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:gravity="center_horizontal"
                  android:orientation="vertical"
                  android:paddingTop="@dimen/padding_small_5dp">
        <TextView
            android:id="@+id/tv_image_index"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <com.cmcc.carelves.ui.component.ShowImagesViewPager
            android:id="@+id/vp_images"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"/>
    
    </LinearLayout>
    

    5.初始化数据

    到了这一步,只需要根据图片url集合配置Glide装载到photoview中,并将photoview添加到viewpager中就可以了,对了,为了photoview的正常显示,还必须给其设置布局参数。(viewpager适配器的代码大多都是写死的,照模板copy份就可以了,下面不贴其代码)

    private void initData() {
    ...
      for (int i = 0; i < mImgUrls.size(); i++) {
        final PhotoView photoView = new PhotoView(mContext);
        ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        photoView.setLayoutParams(layoutParams);
        photoView.setOnPhotoTapListener(listener); //点击事件
        Glide.with(mContext).load(mImgUrls.get(i)).into(new SimpleTarget<GlideDrawable>() {
          @Override
          public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) {
             //photoview重写了设置图片的方法 ,所以不能像普通的imageview去对待
             photoView.setImageDrawable(resource);
            }
          });
            mViews.add(photoView);
            mTitles.add(i + "");
        }
        mAdapter = new ShowImagesAdapter(mViews, mTitles);
        mViewPager.setAdapter(mAdapter);
    ...
    }
    

    6.展示

    展示就按写的构造方法去生成dialog然后show()就可以了。最后附github源码下载:ShowImagesDialogDemo轻量图片浏览方案

    dialog正常显示photoview 同一张图片缩放后的photoview 图片

    相关文章

      网友评论

      • 有没有口罩给我一个:而且我觉得这方案挺好的,不会约束activity和fragment中
      • 有没有口罩给我一个:我的想法和你类似,之前在做朋友圈预览图片也是使用dialog
      • 耀东wang:怎么加载不出来图片啊
      • 盼盼_d7c2:您好,我想问一下,为什么单击图片外面的背景,dialog没有消失呢,只有单击图片上才能消失
      • A_si:输入框的emoji怎么实现的
      • b431631f8cfa:存在一个bug,来回切换后,单点击事件无效,无法返回。
      • 宅居居士:赞一个!
        大天使之剣:@宅居居士 谢谢 哈哈
      • 916b518c2e0d:大神,俺在自己的代码里用了你的方法,可是出错了,
        android.view.InflateException: Binary XML file line #8: Error inflating class com.damon43.showimagesdialogdemo.component.ShowImagesViewPager

        第一句话就指的是mView = View.inflate(mContext,R.layout.dialog_images_brower,null);
        大天使之剣:@紫色的仙人绦 : 哈哈 没事
        916b518c2e0d:@国服第一上单 额,我再研究研究,谢谢大哥指点!:blush:
        大天使之剣:猜测如果是这一行报错的话,估计是没有引入ShowImagesViewPager这个类呢,其实也就是一个为了解决photoview嵌套viewpager时缩放动作崩溃的bug。
      • 蜉杰辰蝣:源码可有?急求
        大天使之剣:好的 ,这是github下载地址:https://github.com/DamonEle/ShowImagesDialogDemo.git
      • b408b9daab58:不错,之前用的activity确实显得太笨重了
        大天使之剣: @画船听雨眠king 是的😁

      本文标题:PhotoView+Glide+Dialog+ViewPager

      本文链接:https://www.haomeiwen.com/subject/aqbrtxtx.html