1. 程式人生 > >實現類似於QQ空間相簿的點選圖片放大,再點後縮小回原來位置

實現類似於QQ空間相簿的點選圖片放大,再點後縮小回原來位置

package com.kale.gridviewanimtest;


import android.graphics.Point;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import android.widget.AdapterView;

import com.nineoldandroids.animation.Animator;
import com.nineoldandroids.animation.AnimatorListenerAdapter; import com.nineoldandroids.animation.AnimatorSet; import com.nineoldandroids.animation.ObjectAnimator; public class ZoomTutorial { final private int mAnimationDuration = 300;// 動畫持續的時間,300比較合適 private Animator mCurrentAnimator;//
當前的動畫物件 private View mContainView;//當前螢幕中檢視最外層的容器 private ViewGroup mThumbViewParent;//小圖片的檢視 private View mExpandedView;//大圖片所在的檢視 private Rect startBounds;//開始動畫的區域範圍 private float startScale;//開始的比率 private float startScaleFinal;//結束時的比率 public ZoomTutorial(View containerView,View expandedView) { mContainView
= containerView; mExpandedView = expandedView; } /** * 十分重要的一個方法,用於展示大的圖片 * * @param thumbView * @param imageResId */ public void zoomImageFromThumb(final View thumbView) { mThumbViewParent = (ViewGroup) thumbView.getParent(); // If there's an animation in progress, cancel it immediately and // proceed with this one. if (mCurrentAnimator != null) { mCurrentAnimator.cancel(); } // Calculate the starting and ending bounds for the zoomed-in image. // This step involves lots of math. Yay, math. // 計算開始和結束的邊界+偏移量 startBounds = new Rect(); final Rect finalBounds = new Rect();// 結束的邊界 final Point globalOffset = new Point();// 目標偏移量 // The start bounds are the global visible rectangle of the thumbnail, // 開始的邊界是小圖整體可見部分的範圍 // and the final bounds are the global visible rectangle of the container view. // 結束的邊界是容器的邊界 // Also set the container view's offset as the origin for the bounds, // since that's the origin for the positioning animation properties (X, Y). thumbView.getGlobalVisibleRect(startBounds); // 這裡的id,container是整個佈局最外層的容器 mContainView.getGlobalVisibleRect(finalBounds, globalOffset); // 開始設定偏移量 startBounds.offset(-globalOffset.x, -globalOffset.y); finalBounds.offset(-globalOffset.x, -globalOffset.y); //設定縮放的比例和位置 set_Center_crop(finalBounds); mExpandedView.setVisibility(View.VISIBLE); // Set the pivot point for SCALE_X and SCALE_Y transformations to the // top-left corner of // the zoomed-in view (the default is the center of the view). AnimatorSet animSet = new AnimatorSet(); animSet.setDuration(1); animSet.play(ObjectAnimator.ofFloat(mExpandedView, "pivotX", 0f)) .with(ObjectAnimator.ofFloat(mExpandedView, "pivotY", 0f)) .with(ObjectAnimator.ofFloat(mExpandedView, "alpha", 1.0f)); animSet.start(); startZoomAnim(mExpandedView, startBounds, finalBounds, startScale); // Upon clicking the zoomed-in image, it should zoom back down to the // original bounds and show the thumbnail instead of the expanded image. startScaleFinal = startScale; } /** * 通過結束的邊界計算開始拉伸的比例 * * Adjust the start bounds to be the same aspect ratio as the final bounds * using the "center crop" technique. 通過 center * crop演算法來調整開始邊界,讓它和的結束邊界保持同一個縱橫比例,也就是長寬比 This prevents undesirable * stretching during the animation.//在動畫執行時保證不讓圖片拉伸 Also calculate the start * scaling factor (the end scaling factor is always 1.0). * 我們也需要計算開始的比率因子,結束比例一直是1.0.因為是將圖片從小放到自己的大小。 */ private void set_Center_crop(Rect finalBounds) { if ((float) finalBounds.width() / finalBounds.height() > (float) startBounds.width() / startBounds.height()) { // Extend start bounds horizontally startScale = (float) startBounds.height() / finalBounds.height(); float startWidth = startScale * finalBounds.width(); float deltaWidth = (startWidth - startBounds.width()) / 2; startBounds.left -= deltaWidth; startBounds.right += deltaWidth; } else { // Extend start bounds vertically startScale = (float) startBounds.width() / finalBounds.width(); float startHeight = startScale * finalBounds.height(); float deltaHeight = (startHeight - startBounds.height()) / 2; startBounds.top -= deltaHeight; startBounds.bottom += deltaHeight; } } /** * @param v 執行動畫的view * @param startBounds 開始的邊界 * @param finalBounds 結束時的邊界 * @param startScale 開始的拉伸比率 */ public void startZoomAnim(View v, Rect startBounds, Rect finalBounds, float startScale) { // Construct and run the parallel animation of the four translation and // scale properties (X, Y, SCALE_X, and SCALE_Y). AnimatorSet set = new AnimatorSet(); set.play( ObjectAnimator.ofFloat(v, "x", startBounds.left, finalBounds.left)) .with(ObjectAnimator.ofFloat(v, "y", startBounds.top, finalBounds.top)) .with(ObjectAnimator.ofFloat(v, "scaleX", startScale, 1f)) .with(ObjectAnimator.ofFloat(v, "scaleY", startScale, 1f)); set.setDuration(mAnimationDuration); set.setInterpolator(new DecelerateInterpolator()); set.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mCurrentAnimator = null; if (listener != null) { listener.onExpanded(); } } @Override public void onAnimationCancel(Animator animation) { mCurrentAnimator = null; if (listener != null) { listener.onExpanded(); } } }); set.start(); mCurrentAnimator = set; } /** * 在GridView中,使用getChildAt(index)的取值,只能是當前可見區域(列表可滾動)的子項! * 因為子項會進行復用。這裡強制轉換了下,變成了GridView,實際使用中需要進行修改 * 【參考】 * http://xie2010.blog.163.com/blog/static/211317365201402395944633/ * http://blog.csdn.net/you_and_me12/article/details/7271006 * * @param position * @return 判斷這個position的view是否現在顯示在螢幕上,如果沒有顯示就返回false */ public boolean getScaleFinalBounds(int position) { //得到顯示區域中第一個子檢視的序號 int firstPosition = ((AdapterView<?>)mThumbViewParent).getFirstVisiblePosition(); View childView = mThumbViewParent.getChildAt(position - firstPosition); startBounds = new Rect(); final Rect finalBounds = new Rect(); final Point globalOffset = new Point(); try { //通過這個計算startBounds,得到當前view的位置,從而設定偏移值 childView.getGlobalVisibleRect(startBounds); } catch (Exception e) { return false; } mContainView.findViewById(R.id.container).getGlobalVisibleRect(finalBounds, globalOffset); startBounds.offset(-globalOffset.x, -globalOffset.y); finalBounds.offset(-globalOffset.x, -globalOffset.y); //設定比率 set_Center_crop(finalBounds); startScaleFinal = startScale; return true; } /** * 根據position執行動畫,如果這個圖片在當前螢幕顯示範圍內,那就執行縮小。否則直接漸變 * @param position */ public void closeZoomAnim(int position) { if (mCurrentAnimator != null) { mCurrentAnimator.cancel(); } // Animate the four positioning/sizing properties in parallel,back to their original values. AnimatorSet set = new AnimatorSet(); /** * 因為展開圖可能是在viewpager中,所以現在顯示的圖片,或許並不是第一次開啟的圖片,這裡應該考慮兩點 * 1.改變圖片縮小後回到的位置 * 2.如果圖片縮小後回到的位置不在螢幕中,直接漸變消失 */ boolean isInBound = getScaleFinalBounds(position); if (isInBound) { set.play(ObjectAnimator.ofFloat(mExpandedView, "x", startBounds.left)) .with(ObjectAnimator.ofFloat(mExpandedView, "y", startBounds.top)) .with(ObjectAnimator.ofFloat(mExpandedView, "scaleX", startScaleFinal)) .with(ObjectAnimator.ofFloat(mExpandedView, "scaleY", startScaleFinal)); } else { // 如果當前顯示的圖片不在gridview當前顯示的圖片中,等於越界了。這時我們就不執行縮放操作,直接漸變消失即可。 ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(mExpandedView, "alpha", 0.1f); set.play(alphaAnimator); } set.setDuration(mAnimationDuration); set.setInterpolator(new DecelerateInterpolator()); set.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mExpandedView.clearAnimation(); mExpandedView.setVisibility(View.GONE); mCurrentAnimator = null; if (listener != null) { listener.onThumbed(); } } @Override public void onAnimationCancel(Animator animation) { mExpandedView.clearAnimation(); mExpandedView.setVisibility(View.GONE); mCurrentAnimator = null; if (listener != null) { listener.onThumbed(); } } }); set.start(); mCurrentAnimator = set; } private OnZoomListener listener; public void setOnZoomListener(OnZoomListener l) { listener = l; } public interface OnZoomListener { public void onExpanded();//點選後展示大圖成功後呼叫 public void onThumbed();//點選後縮小回小圖時呼叫 } }

相關推薦

實現類似QQ空間相簿圖片放大縮小原來位置

package com.kale.gridviewanimtest; import android.graphics.Point; import android.graphics.Rect; import android.view.View; import android.view.Vie

圖片放大縮小的程式碼段

這段js還挺常用,特此記錄。 1 <form> 2   <div> 3 <div class="form-group left"> 4 <label for="imgs" class="col-sm-3 cont

利用html和Jquery實現照片牆(之後放大縮小

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <script src="js/jque

小程式圖片放大長按儲存

//點選圖片進行預覽,長按儲存分享圖片 previewImg: function (e) { var img = this.data.imagePath;  //需要儲存圖片的路徑 console.log(img); wx.previewImage({ curren

[js]多個按鈕新增div刪除

主要思想是一個全域性變數來控制增加或刪除。點一下顯示,再點一下刪除。 原始碼如下,可直接執行 <!DOCTYPE html> <html> <head>

微信內網頁安卓圖片放大與IOS失效處理方法

 // 遞迴搜尋當前元素所有父級,看是否包含有a標籤且有href值const searchIsHavaTagA = function (currentEle) {    // 如果一直往上層找,到body還沒找到就說明沒有了    if (currentEle.nodeName === 'BODY') {  

SwipeMenuListView實現類似QQ側滑刪除效果

前言:最近,因為專案需要實現刪除功能,為了美觀採用了類似於QQ的那種側滑刪除效果,使用的是SwipeMenuListView的開源控制元件,現將使用方法記錄分享一下,有興趣的童鞋可以看看。效果如下圖: 1、新增依賴 方法1:下載開源庫程式碼,將程式碼複

批量登入qq空間推廣連結增加

原始碼請至此處下載:https://github.com/inmyjs/apqq_space 或者直接下載打包好的,https://download.csdn.net/download/kunoy/10652361 ,下載解壓,點選start.exe啟動。 此軟體適合在qq

websocket實現類似QQ的聊天功能

使用websocket實現聊天的原因 http單向通訊協議,請求只能是客戶端發起,且是無狀態的,而websocket是雙向通訊協議,可以有伺服器發起也可以是客戶端發起,用http實現聊天功能一般是通過輪詢,但是輪詢非常浪費伺服器資源,而且慢,親測過 重點websocket

vue實現圖片放大圖片

### 使用vue一個元件vue-directive-image-previewer A Vue.js project for tag img, click img to zoom out to ful

簡單實現圖片放大的功能

背景:想在app中加上點選縮圖放大的效果,但是不想匯入大量的JS ,也無需哪些複雜的外掛,於是自己手寫了一個很簡單的實現,在這裡記下來。 程式碼很簡單,還有很多優化空間,時間有限,就沒有優化了 1 . 先準備大圖的位置 大圖是fixed於整個介面,只修改其中的s

HTML:如何圖片上的某個實現對映連結

廢話不多說,附上程式碼 <img src="planets.gif" width="145" height="126" alt="Planets" usemap="#planetmap"> <map name="planetmap">   <area

iOS 實現圖片放大&長按儲存圖片

一:簡介 在專案中免不了會遇到,實名認證上傳身份證、繫結銀行卡等功能。在實際操作中呢,會涉及到上傳圖片,在頁面佈局時,可能圖片不是一張,考慮到佈局的美觀等因素,顯示圖片的位置變得很小,如果想檢視上傳的圖片是否清晰,內容是否完整,可能就需要放大才能實現,下面就和大家分享一下我封裝的一類,完美的

gridview顯示圖片實現圖片放大縮小

一、建立一個gridview控制元件,並新增列。 其中ImageField就是顯示圖片的列,屬性DataImagteUrlField繫結為圖片的路徑,也就是資料庫儲存圖片路徑的欄位名。 二、建立一個用來顯示大圖片的div 以及Img控制元件。以及css樣式、js。

iOS實現圖片放大&長按儲存圖片

一:簡介 在專案中免不了會遇到,實名認證上傳身份證、繫結銀行卡等功能。在實際操作中呢,會涉及到上傳圖片,在頁面佈局時,可能圖片不是一張,考慮到佈局的美觀等因素,顯示圖片的位置變得很小,如果想檢視上傳的圖片是否清晰,內容是否完整,可能就需要放大才能實現,下面就和

js圖片放大

HTML程式碼: 1 <img id="img0" src="" style="padding-right:10px; " /> 2 3 <div id="myModal" class="modal"> 4 <!-- 關閉按鈕

微信小程式圖片放大預覽

微信小程式點選圖片放大預覽使用到 wx.previewImage 介面,可以放大、上/下一張 上程式碼 wxml程式碼 <view class='content-img' wx:if="{{images}}" > <view wx:for="{{i

jQuery 圖片放大 燈箱效果

使用外掛lightBox2,原文及例項程式碼: http://www.shouce.ren/study/api/s/6948 github地址:https://github.com/lokesh/lightbox2/   引入js及 css <link rel="

圖片放大的效果(如果幫助大關注我後期更好的作品奧)

第一步,要下載燈箱這個外掛 連線:連結: https://pan.baidu.com/s/1o1mYq5oIfo87YSQF9kjy8w 提取碼: used 下載並且解壓到本地 3.1本地的燈箱解壓如圖 進入src 目錄 如下圖 5.1 專案目錄如下 6.HTM

圖片放大縮小功能

1.點選圖片放大縮小的思路 圖片部分: <table> <div> <img style="width:62px;height:83px;display:block" src="${photourl}" onclick="showMaxImg(thi