国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android仿頭條、微信大圖預覽視圖的方法詳解

2019-10-22 18:13:52
字體:
來源:轉載
供稿:網友

圖片大圖預覽

在我現在的項目當中,也存在大圖預覽的功能,但其實現過于繁重,采用一個Activity實現,并且在圖片展示的過程中會產生卡頓感,整體感覺很是不好,正巧項目也在重構過程中,所以決定將這一功能寫成一個成型的控件。

話不多說,先上圖看下效果。

android,微信查看大圖,微信圖片預覽,大圖預覽

整體實現思路

圖片展示:PhotoView(大圖支持雙擊放大)
圖片加載:Glide(加載網絡圖片、本地圖片、資源文件)
小圖變大圖時的實現:動畫
圖片的下載:插入系統相冊

該控件采用自定義View的方式,通過一些基本的控件的組合,來形成一個具有大圖預覽的控件。上代碼

使用方法

(1)在布局文件中引用該view

<com.demo.gallery.view.GalleryView android/80200.html">android/191007.html">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, List, 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, translationX, translationY, scale, 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", startTranslationY, endTranslationY))    .with(ObjectAnimator.ofFloat(scaleImageView, "scaleX", startScale, endScale))    .with(ObjectAnimator.ofFloat(scaleImageView, "scaleY", startScale, endScale))    // ---Alpha動畫---    // mMaskView伴隨著一個Alpha減小動畫    .with(ObjectAnimator.ofFloat(maskView, "alpha", startAlpha, endAlpha));  set.setDuration(animDuration);  if (listener != null) {   set.addListener(listener);  }  set.setInterpolator(new DecelerateInterpolator());  set.start(); }

改View的主要實現如上,在圖片進行縮放的時候,要考慮的情況:短邊適配、圖片原尺寸的寬高、展示圖片的ImageView的寬高比、橫豎屏時屏幕的尺寸。在此非常感謝震哥的幫助、抱拳了!老鐵。如有更多想法的小伙伴。

請移步我的github  GalleryView地址

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VEVB武林網的支持。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 开化县| 长汀县| 盘山县| 怀仁县| 遂溪县| 东乡族自治县| 新巴尔虎左旗| 三门县| 苗栗市| 板桥市| 濉溪县| 香港| 桐梓县| 潢川县| 东光县| 四会市| 安多县| 咸丰县| 阜康市| 密山市| 淮安市| 彭山县| 文昌市| 民勤县| 宕昌县| 仙桃市| 乌拉特中旗| 米林县| 绥化市| 乐至县| 永年县| 兴宁市| 静海县| 东安县| 游戏| 凭祥市| 浙江省| 白沙| 炉霍县| 安达市| 桑日县|