Jetpack學習——使用動畫縮放圖片

我們的app經(jīng)常遇到這樣一種場景照雁,就是小圖到大圖的轉換避矢,這時候如果有個縮放動畫就會很自然。本節(jié)將介紹如何使用動畫進行縮放圖片,在點擊頭像看大圖這種場景可以使用审胸。本文的例子的示意圖如下所示:

使用動畫縮放圖片示例

創(chuàng)建View

布局主要包含兩個View亥宿,一個ImageButton用于加載縮略圖,一個ImageView用于顯示大圖砂沛。

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    android:id="@+id/container"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".animation.EnlargeImageActivity">

    <ImageButton
        android:id="@+id/imageBtn"
        android:layout_width="100dp"
        android:layout_height="75dp"
        android:scaleType="centerCrop"
        android:src="@drawable/pic_11"/>

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/pic_11"
        android:visibility="invisible"/>

</android.support.constraint.ConstraintLayout>

設置縮放動畫

ImageButtton觸發(fā)動畫烫扼,這里就不贅述了。

縮放動畫

大體上碍庵,你需要從正常尺寸的View的界限動畫到大尺寸的View的界限映企。下面的方法通過四步介紹了如何實現(xiàn)一個從縮略圖到大圖的放大動畫。

  1. 分配大圖給ImageView静浴,即放大后的View堰氓。下面的代碼是在主線程中加載圖片的,這個過程在現(xiàn)實app中一般是要進行網(wǎng)絡操作的苹享,需要放在非UI線程双絮。理想狀態(tài)下,這個圖片的尺寸是不應該超過屏幕尺寸的得问。

  2. 計算ImageView的起始和結束尺寸囤攀。

  3. 從起始尺寸同時動畫四個屬性:X、Y宫纬、SCALE_X和SCALE_Y焚挠。這四個參數(shù)一起加入到AnimationSet,以便可以同時動畫漓骚。

  4. 使用一個相似的動畫作用于大的ImageView蝌衔,當點擊后,圖片縮小回去蝌蹂,最后隱藏ImageView徐紧。

從小到大動畫

代碼如下:

//從小到大
    private fun zoomImageFromThumb() {

        mCurrentAnimator?.cancel()

        imageView.setImageResource(R.drawable.pic_11)

        //獲取尺寸
        val startBoundsInt = Rect()
        val finalBoundsInt = Rect()
        val globalOffset = Point()

        imageBtn.getGlobalVisibleRect(startBoundsInt)
        imageView.getGlobalVisibleRect(finalBoundsInt, globalOffset)
        //調整使top=left=0
        startBoundsInt.offset(-globalOffset.x, -globalOffset.y)
        finalBoundsInt.offset(-globalOffset.x, -globalOffset.y)

        val startBounds = RectF(startBoundsInt)
        val finalBounds = RectF(finalBoundsInt)

        //計算寬高縮放比
        val startScale: Float
        if ((finalBounds.width() / finalBounds.height() > startBounds.width() / startBounds.height())) {
            startScale = startBounds.height() / finalBounds.height()
            val startWidth: Float = startScale * finalBounds.width()
            val deltaWidth: Float = (startWidth - startBounds.width()) / 2
            startBounds.left -= deltaWidth.toInt()
            startBounds.right += deltaWidth.toInt()
        } else {
            // Extend start bounds vertically
            startScale = startBounds.width() / finalBounds.width()
            val startHeight: Float = startScale * finalBounds.height()
            val deltaHeight: Float = (startHeight - startBounds.height()) / 2f
            startBounds.top -= deltaHeight.toInt()
            startBounds.bottom += deltaHeight.toInt()
        }

        imageBtn.visibility = View.INVISIBLE
        imageView.visibility = View.VISIBLE

        imageView.pivotX = 0f
        imageView.pivotY = 0f

        mCurrentAnimator = AnimatorSet().apply {
            //x皮胡、y膝晾、scaleX于樟、scaleY四個維度一起動畫
            play(ObjectAnimator.ofFloat(
                    imageView,
                    View.X,
                    startBounds.left,
                    finalBounds.left)
            ).apply {
                with(ObjectAnimator.ofFloat(imageView, View.Y, startBounds.top, finalBounds.top))
                with(ObjectAnimator.ofFloat(imageView, View.SCALE_X, startScale, 1f))
                with(ObjectAnimator.ofFloat(imageView, View.SCALE_Y, startScale, 1f))
            }
            duration = mShortAnimationDuration.toLong()
            interpolator = DecelerateInterpolator()
            addListener(object : AnimatorListenerAdapter() {

                override fun onAnimationEnd(animation: Animator) {
                    mCurrentAnimator = null
                }

                override fun onAnimationCancel(animation: Animator) {
                    mCurrentAnimator = null
                }
            })
            start()
        }
    }

其中有一點說明艘希,寬高采用了同樣的縮放比硼身,但是由于初始尺寸的寬高比不一定完全等于結束時的寬高比,因此會對初始尺寸進行微調覆享,使比例與最終比例一致佳遂。針對我們這里的情況,示意圖如下: ![]

image

初始寬高比大于1撒顿,結束寬高比小于1丑罪,為了統(tǒng)一,對初始尺寸進行調整,如中間圖所示吩屹。

從大到小縮放

從大到小的縮放動畫與上面的動畫相反跪另,這里就不貼代碼了,感興趣的可以去后面找demo地址查看煤搜。

縮放比例不一致的效果

上面的例子與官方類似免绿,都是縮放比例一致。本著好奇心擦盾,試試縮放比例不一致的效果如何嘲驾。

效果如下:

image

反正我是沒怎么看出差距來,看出來的差距的歡迎留言我迹卢。

總結

關于代碼辽故,請移步Github地址。這次對整個項目做了個整理腐碱,更好查看各個demo了誊垢,樣式如下:

新的demo樣式

參考

關注我的技術公眾號,不定期會有優(yōu)質技術文章推送喻杈。微信掃一掃下方二維碼即可關注:


微信公眾號二維碼
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末彤枢,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子筒饰,更是在濱河造成了極大的恐慌缴啡,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瓷们,死亡現(xiàn)場離奇詭異业栅,居然都是意外死亡,警方通過查閱死者的電腦和手機谬晕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門碘裕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人攒钳,你說我怎么就攤上這事帮孔。” “怎么了不撑?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵文兢,是天一觀的道長。 經(jīng)常有香客問我焕檬,道長姆坚,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任实愚,我火速辦了婚禮兼呵,結果婚禮上兔辅,老公的妹妹穿的比我還像新娘。我一直安慰自己击喂,他們只是感情好维苔,可當我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著懂昂,像睡著了一般蕉鸳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上忍法,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天潮尝,我揣著相機與錄音,去河邊找鬼饿序。 笑死勉失,一個胖子當著我的面吹牛,可吹牛的內容都是我干的原探。 我是一名探鬼主播乱凿,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼咽弦!你這毒婦竟也來了徒蟆?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤型型,失蹤者是張志新(化名)和其女友劉穎段审,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體闹蒜,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡寺枉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了绷落。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片姥闪。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖砌烁,靈堂內的尸體忽然破棺而出筐喳,到底是詐尸還是另有隱情,我是刑警寧澤函喉,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布避归,位于F島的核電站,受9級特大地震影響函似,放射性物質發(fā)生泄漏槐脏。R本人自食惡果不足惜喉童,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一撇寞、第九天 我趴在偏房一處隱蔽的房頂上張望顿天。 院中可真熱鬧,春花似錦蔑担、人聲如沸牌废。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鸟缕。三九已至,卻和暖如春排抬,著一層夾襖步出監(jiān)牢的瞬間懂从,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工蹲蒲, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留番甩,地道東北人。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓届搁,卻偏偏與公主長得像缘薛,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子卡睦,可洞房花燭夜當晚...
    茶點故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內容

  • 1 CALayer IOS SDK詳解之CALayer(一) http://doc.okbase.net/Hell...
    Kevin_Junbaozi閱讀 5,128評論 3 23
  • 發(fā)現(xiàn) 關注 消息 iOS 第三方庫宴胧、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,029評論 4 62
  • 7.1 壓縮圖片 一表锻、基礎知識 1恕齐、圖片的格式 jpg:最常見的圖片格式。色彩還原度比較好瞬逊,可以支持適當壓縮后保持...
    AndroidMaster閱讀 2,487評論 0 13
  • 深夜十二點半檐迟,輾轉難眠,各種調節(jié)各種深呼吸码耐,都無法緩解失眠的現(xiàn)狀追迟。 窗外傳來鄰家喵咪的叫聲,遠處有青蛙的呱呱聲骚腥,還...
    顏容閱讀 839評論 1 4
  • 每日一問: 每日一答: 作業(yè): 隱身日:如果你會隱身術敦间,你要干嘛?如果讓你匿名表達一些觀點束铭,你要對誰說些什么廓块?匿名...
    Tracy_2017閱讀 96評論 0 0