Android仿头条、微信大图预览视图的方法详解

Android仿头条、微信大图预览视图的方法详解,第1张

概述图片大图预览在我现在的项目当中,也存在大图预览的功能,但其实现过于繁重,采用一个Activity实现,并且在图片展示的过程中会产生卡顿感,整体感觉很是不好,正巧项目也在重构过程中,所以决定将这一功能写成一个成

图片大图预览

在我现在的项目当中,也存在大图预览的功能,但其实现过于繁重,采用一个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 实现WebView点击图片查看大图列表及图片保存功能Android中超大图片无法显示的问题解决Android高效加载大图、多图解决方案 有效避免程序OOMAndroid 实现加载大图片的方法Android编程实现大图滚动显示的方法Android 加载大图、多图和LruCache缓存详细介绍Android实现网络加载图片点击大图后浏览可缩放Android实现大图滚动显示效果 总结

以上是内存溢出为你收集整理的Android仿头条、微信大图预览视图的方法详解全部内容,希望文章能够帮你解决Android仿头条、微信大图预览视图的方法详解所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1142869.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存