图片大图预览
在我现在的项目当中,也存在大图预览的功能,但其实现过于繁重,采用一个Activity实现,并且在图片展示的过程中会产生卡顿感,整体感觉很是不好,正巧项目也在重构过程中,所以决定将这一功能写成一个成型的控件。
话不多说,先上图看下效果。
整体实现思路
图片展示:PhotoVIEw(大图支持双击放大)
图片加载:GlIDe(加载网络图片、本地图片、资源文件)
小图变大图时的实现:动画
图片的下载:插入系统相册
该控件采用自定义view的方式,通过一些基本的控件的组合,来形成一个具有大图预览的控件。上代码
使用方法
(1)在布局文件中引用该vIEw
<com.demo.gallery.vIEw.galleryVIEw androID:ID="@+ID/photo_gallery_vIEw" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:visibility="gone" app:animDuration="300" app:saveText="保存至相册" app:saveTextcolor="#987622"/>
(2)具体使用方法
galleryVIEw galleryVIEw = findVIEwByID(R.ID.photo_gallery_vIEw);galleryVIEw.showPhotogallery(index,List,ImageVIEw);
到这里就结束了,就是这么简单!
具体实现
(1)先从showPhotogallery(index,ImageVIEw)这个方法讲起
int index:我们想要展示的一个图片列表中的第几个
List List: 我们要传入的要展示的图片类型List(支持网络图片、资源图片、本地图片(本地图片与网络图片其实都是一个字符串地址))
public class galleryPhotoModel { public Object photoSource; public galleryPhotoModel(@DrawableRes int drawableRes) { this.photoSource = drawableRes; } public galleryPhotoModel(String path) { this.photoSource = path; }}
ImageVIEw:即你点击想要展示的那个图片
(2)对传入galleryVIEw的数据进行处理
/** * @param index 想要展示的图片的索引值 * @param photoList 图片集合(URL、Drawable、Bitmap) * @param clickImageVIEw 点击的第一个图片 */ public voID showPhotogallery(int index,List<galleryPhotoModel> photoList,ImageVIEw clickImageVIEw) { galleryPhotoparameterModel photoparameter = new galleryPhotoparameterModel(); //图片 photoparameter.photoObj = photoList.get(index).photoSource; //图片在List中的索引 photoparameter.index = index; int[] locationOnScreen = new int[2]; //图片位置参数 clickImageVIEw.getLocationOnScreen(locationOnScreen); photoparameter.locOnScreen = locationOnScreen; //图片的宽高 int wIDth = clickImageVIEw.getDrawable().getBounds().wIDth(); int height = clickImageVIEw.getDrawable().getBounds().height(); photoparameter.imageWIDth = clickImageVIEw.getWIDth(); photoparameter.imageHeight = clickImageVIEw.getHeight(); photoparameter.photoHeight = height; photoparameter.photoWIDth = wIDth; //scaleType photoparameter.scaleType = clickImageVIEw.getScaleType(); //将第一个点击的图片参数连同整个图片列表传入 this.setVisibility(VIEw.VISIBLE); post(new Runnable() { @OverrIDe public voID run() { requestFocus(); } }); setgalleryPhotoList(photoList,photoparameter); }
通过传递进来的ImageVIEw,获取被点击VIEw参数,并拼装成参数model,再进行数据的相关处理。
(3)galleryVIEw的实现机制
该VIEw的实现思路主要是:最外层是一个relativeLayout,内部有一个充满父布局的ImageVIEw和VIEwPager。ImageVIEw用来进行图片的动画缩放,VIEwPager用来进行最后的图片的展示。其实该VIEw最主要的地方就是通过点击ImageVIEw到最后VIEwPager的展示的动画。接下来主要是讲解一下这个地方。先看一下被点击ImageVIEw的参数Model。galleryPhotoparameterModel
public class galleryPhotoparameterModel { //索引 public int index; // 图片的类型 public Object photoObj; // 在屏幕上的位置 public int[] locOnScreen = new int[]{-1,-1}; // 图片的宽 public int photoWIDth = 0; // 图片的高 public int photoHeight = 0; // ImageVIEw的宽 public int imageWIDth = 0; // ImageVIEw的高 public int imageHeight = 0; // ImageVIEw的缩放类型 public ImageVIEw.ScaleType scaleType;}
3.1图片放大 *** 作
private voID handleZoomAnimation() { // 屏幕的宽高 this.mScreenRect = galleryScreenUtil.getdisplayPixes(getContext()); //将被缩放的图片放在一个单独的ImageVIEw上进行单独的动画处理。 GlIDe.with(getContext()).load(firstClickItemParameterModel.photoObj).into(mScaleImageVIEw); //开启动画 mScaleImageVIEw.getVIEwTreeObserver().addOnGlobalLayoutListener(new VIEwTreeObserver.OnGlobalLayoutListener() { @OverrIDe public voID onGlobalLayout() { //开始放大 *** 作 calculateScaleAndStartZoomInAnim(firstClickItemParameterModel); // mScaleImageVIEw.getVIEwTreeObserver().removeGlobalOnLayoutListener(this); } }); }
/** * 计算放大比例,开启放大动画 * * @param photoData */ private voID calculateScaleAndStartZoomInAnim(final galleryPhotoparameterModel photoData) { mScaleImageVIEw.setVisibility(VIEw.VISIBLE); // 放大动画参数 int translationX = (photoData.locOnScreen[0] + photoData.imageWIDth / 2) - (int) (mScreenRect.wIDth() / 2); int translationY = (photoData.locOnScreen[1] + photoData.imageHeight / 2) - (int) ((mScreenRect.height() + galleryScreenUtil.getStatusbarHeight(getContext())) / 2); float scale = getimageVIEwScale(photoData); // 开启放大动画 executeZoom(mScaleImageVIEw,translationX,translationY,scale,true,new Animator.AnimatorListener() { @OverrIDe public voID onAnimationStart(Animator animation) {} @OverrIDe public voID onAnimationEnd(Animator animation) { showOtherVIEws(); tvPhotoSize.setText(String.format("%d/%d",vIEwPager.getCurrentItem() + 1,photoList.size())); } @OverrIDe public voID onAnimationCancel(Animator animation) { } @OverrIDe public voID onAnimationRepeat(Animator animation) { } }); }
3.2 图片缩小 *** 作
/** * 计算缩小比例,开启缩小动画 */ private voID calculateScaleAndStartZoomOutAnim() { hIEdOtherVIEws(); // 缩小动画参数 int translationX = (firstClickItemParameterModel.locOnScreen[0] + firstClickItemParameterModel.imageWIDth / 2) - (int) (mScreenRect.wIDth() / 2); int translationY = (firstClickItemParameterModel.locOnScreen[1] + firstClickItemParameterModel.imageHeight / 2) - (int) ((mScreenRect.height() + galleryScreenUtil.getStatusbarHeight(getContext())) / 2); float scale = getimageVIEwScale(firstClickItemParameterModel); // 开启缩小动画 executeZoom(mScaleImageVIEw,false,new Animator.AnimatorListener() { @OverrIDe public voID onAnimationStart(Animator animation) {} @OverrIDe public voID onAnimationEnd(Animator animation) { mScaleImageVIEw.setimageDrawable(null); mScaleImageVIEw.setVisibility(GONE); setVisibility(GONE); } @OverrIDe public voID onAnimationCancel(Animator animation) {} @OverrIDe public voID onAnimationRepeat(Animator animation) {} }); }
3.3 计算图片缩放的比例
private float getimageVIEwScale(galleryPhotoparameterModel photoData) { float scale; float scaleX = photoData.imageWIDth / mScreenRect.wIDth(); float scaleY = photoData.photoHeight * 1.0f / mScaleImageVIEw.getHeight(); // 横向图片 if (photoData.photoWIDth > photoData.photoHeight) { // 图片的宽高比 float photoScale = photoData.photoWIDth * 1.0f / photoData.photoHeight; // 执行动画的ImageVIEw宽高比 float animationImageScale = mScaleImageVIEw.getWIDth() * 1.0f / mScaleImageVIEw.getHeight(); if (animationImageScale > photoScale) { // 动画ImageVIEw宽高比大于图片宽高比的时候,需要用图片的高度除以动画ImageVIEw高度的比例尺 scale = scaleY; } else { scale = scaleX; } } // 正方形图片 else if (photoData.photoWIDth == photoData.photoHeight) { if (mScaleImageVIEw.getWIDth() > mScaleImageVIEw.getHeight()) { scale = scaleY; } else { scale = scaleX; } } // 纵向图片 else { scale = scaleY; } return scale; }
3.4 执行动画的缩放
/** * 执行缩放动画 * @param scaleImageVIEw * @param translationX * @param translationY * @param scale * @param isEnlarge */ private voID executeZoom(final ImageVIEw scaleImageVIEw,int translationX,int translationY,float scale,boolean isEnlarge,Animator.AnimatorListener Listener) { float startTranslationX,startTranslationY,endTranslationX,endTranslationY; float startScale,endScale,startAlpha,endAlpha; // 放大 if (isEnlarge) { startTranslationX = translationX; endTranslationX = 0; startTranslationY = translationY; endTranslationY = 0; startScale = scale; endScale = 1; startAlpha = 0f; endAlpha = 0.75f; } // 缩小 else { startTranslationX = 0; endTranslationX = translationX; startTranslationY = 0; endTranslationY = translationY; startScale = 1; endScale = scale; startAlpha = 0.75f; endAlpha = 0f; } //-------缩小动画-------- AnimatorSet set = new AnimatorSet(); set.play( ObjectAnimator.offloat(scaleImageVIEw,"translationX",startTranslationX,endTranslationX)) .with(ObjectAnimator.offloat(scaleImageVIEw,"translationY",endTranslationY)) .with(ObjectAnimator.offloat(scaleImageVIEw,"scaleX",startScale,endScale)) .with(ObjectAnimator.offloat(scaleImageVIEw,"scaleY",endScale)) // ---Alpha动画--- // mMaskVIEw伴随着一个Alpha减小动画 .with(ObjectAnimator.offloat(maskVIEw,"Alpha",endAlpha)); set.setDuration(animDuration); if (Listener != null) { set.addListener(Listener); } set.setInterpolator(new DecelerateInterpolator()); set.start(); }
改VIEw的主要实现如上,在图片进行缩放的时候,要考虑的情况:短边适配、图片原尺寸的宽高、展示图片的ImageVIEw的宽高比、横竖屏时屏幕的尺寸。在此非常感谢震哥的帮助、抱拳了!老铁。如有更多想法的小伙伴。
请移步我的github GalleryView地址
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对编程小技巧的支持。
以上是内存溢出为你收集整理的Android仿头条、微信大图预览视图的方法详解全部内容,希望文章能够帮你解决Android仿头条、微信大图预览视图的方法详解所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)