滑動(dòng)內(nèi)聯(lián)動(dòng)效的實(shí)現(xiàn)之item的伴生變換

本文屬于滑動(dòng)內(nèi)聯(lián)動(dòng)效系列的第二篇。倉(cāng)庫(kù)地址

滑動(dòng)內(nèi)聯(lián)動(dòng)效 指的是 在容器滑動(dòng)的過(guò)程中考传,其子View對(duì)應(yīng)展現(xiàn)出來(lái)的一些效果招拙。本篇主要記錄的是在容器滑動(dòng)過(guò)程中,它的item伴隨進(jìn)行縮放和透明度變化喇勋。

上圖缨该,明了。

圖1.gif

圖1中川背,隨著滑動(dòng)贰拿,內(nèi)部item呈現(xiàn)先變大再變小的趨勢(shì),同時(shí)透明度上也是先變亮在變暗的趨勢(shì)渗常。

圖2.gif

圖2中壮不,主要是橫向的一些特效,分別有圖片逆差效果皱碘,縮放效果以及透明度變換效果询一。

方案分析

思路基本同滑動(dòng)內(nèi)聯(lián)動(dòng)效的實(shí)現(xiàn)之圖片平行逆差效果,整體還是需要一個(gè)自定義的伴生容器,作為內(nèi)聯(lián)item的父布局健蕊。在實(shí)現(xiàn)方式上還是有些差別菱阵。具體分析步驟如下:

  • 1 獲得外面滑動(dòng)容器的滑動(dòng)事件。
    因?yàn)槭亲龌瑒?dòng)內(nèi)聯(lián)效果缩功,那么理應(yīng)得到滑動(dòng)事件才行晴及。還是跟其上篇一樣,使用ViewTreeObserver.OnScrollChangedListener這個(gè)接口嫡锌。

  • 2 得到滑動(dòng)容器的位置范圍虑稼。
    這個(gè)滑動(dòng)容器可大可小,滑動(dòng)內(nèi)聯(lián)效果肯定是與這個(gè)有關(guān)系的势木。假設(shè)有個(gè)點(diǎn)蛛倦,剛好位于滑動(dòng)容器的最下邊。當(dāng)滑動(dòng)進(jìn)行時(shí)啦桌,這個(gè)點(diǎn)便會(huì)跟著向下移動(dòng)溯壶,當(dāng)其到滑動(dòng)容器最上邊時(shí),這個(gè)點(diǎn)剛好走了滑動(dòng)容器的上下距離甫男。這個(gè)過(guò)程且改,也代表了比較理想的內(nèi)聯(lián)動(dòng)效的起始和最終位置。這個(gè)容器范圍可表示為屏幕上的一個(gè)矩形板驳,這個(gè)矩形可以在滑動(dòng)容器顯示到屏幕上時(shí)動(dòng)態(tài)的設(shè)置給內(nèi)部item又跛。

  • 3 確定包裝容器和圖片的內(nèi)聯(lián)滑動(dòng)
    滑動(dòng)開始了,也知道什么時(shí)候內(nèi)聯(lián)滑動(dòng)開始了笋庄,那么內(nèi)聯(lián)容器應(yīng)該怎么內(nèi)聯(lián)呢效扫。這個(gè)涉及一些數(shù)學(xué)計(jì)算。與圖片內(nèi)聯(lián)效果有些不同的是直砂,在縮放和透明度變化上菌仁,這里有兩種比較常見(jiàn)的展示。
    - 線性計(jì)算:隨著滑動(dòng)静暂,item的屬性線性單調(diào)變化济丘;
    - 曲線變化:隨著滑動(dòng),item的屬性先變大再變小洽蛀,使得item位于容器中間時(shí)屬性最明顯摹迷。

這里再聲明一下兩個(gè)概念:
a- 滑動(dòng)容器:即平時(shí)用的具有滑動(dòng)效果的View,比如ListView,RecyclerView郊供;
b- 內(nèi)聯(lián)容器:使其內(nèi)容具有伴生效果的ViewGroup峡碉;
c- 內(nèi)聯(lián)item:在滑動(dòng)容器滑動(dòng)時(shí),具有伴生動(dòng)效的item驮审,其父布局是內(nèi)聯(lián)容器鲫寄,普通item放到內(nèi)聯(lián)容器中吉执,即為內(nèi)聯(lián)item。

代碼實(shí)現(xiàn)

整體實(shí)現(xiàn)思路同滑動(dòng)內(nèi)聯(lián)動(dòng)效的實(shí)現(xiàn)之圖片平行逆差效果地来,效果只是寫幾個(gè)AdStyle戳玫,然后添加到內(nèi)聯(lián)容器中即可。這里以縱向縮放為例未斑,簡(jiǎn)單分析一下咕宿。

public class VerticalScaleStyle extends SimpleStyle implements AdjointStyle {
    @Override
    public void onAttachedToImageView(AdjointContainer view) {
    }
    @Override
    public void onDetachedFromImageView(AdjointContainer view) {
    }
    @Override
    public void transform(AdjointContainer aContainer, Canvas canvas, int[] viewLocation, Rect parentLocation) {
        //獲得內(nèi)聯(lián)容器的y坐標(biāo)
        int y = viewLocation[1];
        //獲得滑動(dòng)容器的頂部和底部位置
        int ptop = parentLocation.top;
        int pbottom = parentLocation.bottom;
        //獲得內(nèi)聯(lián)容器的內(nèi)部可用寬和高
        int vWidth = aContainer.getWidth() - aContainer.getPaddingLeft() - aContainer.getPaddingRight();
        int vHeight = aContainer.getHeight() - aContainer.getPaddingTop() - aContainer.getPaddingBottom();
        // device's height
        int dHeight = ScreenUtil.getScreenHeight(aContainer.getContext());
        //取滑動(dòng)低點(diǎn)
        dHeight = dHeight < pbottom ? dHeight : pbottom;

        // 避免過(guò)度滑動(dòng)
        if (y < ptop - vHeight) {
            y = ptop - vHeight;
        } else if (y > dHeight) {
            y = dHeight;
        }
        y = y - ptop;
        int itemMaxMoveScope = pbottom - ptop - vHeight;
        float index = y;
        if (index <= 0) {
            index = 1.0f;
        }
        if (index >= itemMaxMoveScope) {
            index = itemMaxMoveScope;
        }
        float al = 1.0f;
        //是否線性計(jì)算
        if (isLinearable()) {
            if (index < getLinearPos() * itemMaxMoveScope) {
                index = 0;
            }
            al = (1 - getMinScale()) * (itemMaxMoveScope - index) / itemMaxMoveScope + getMinScale();
        } else {//非線性實(shí)現(xiàn)
            al = (4 * getMinScale() - 4.0f) * index * index / (itemMaxMoveScope * itemMaxMoveScope)
                    + (4.0f - 4 * getMinScale()) * index / itemMaxMoveScope + getMinScale();
        }
        //設(shè)置最小的縮放比例
        if (al < getMinScale()) {
            al = getMinScale();
        }
        al = al * getFactor();
        canvas.scale(al, al, vWidth/2, vHeight*getPrivotY());
    }
}

使用方式

整體實(shí)現(xiàn)思路同滑動(dòng)內(nèi)聯(lián)動(dòng)效的實(shí)現(xiàn)之圖片平行逆差效果,簡(jiǎn)述為:

  1. 布局蜡秽,內(nèi)聯(lián)容器作為需要內(nèi)聯(lián)item的容器府阀;
  2. 設(shè)置區(qū)域,給內(nèi)聯(lián)容器設(shè)置滑動(dòng)容器的矩形區(qū)域芽突;
  3. 創(chuàng)建一個(gè)或多個(gè)AdjointStyle肌似,添加到內(nèi)聯(lián)容器中。

此時(shí)诉瓦,若是設(shè)置得當(dāng),便會(huì)得到內(nèi)部item隨滑動(dòng)容器滑動(dòng)力细,出現(xiàn)平行逆差/縮放和透明度變化的一種展示效果睬澡。


上面主要介紹了思路。完整例子見(jiàn)github倉(cāng)庫(kù)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末眠蚂,一起剝皮案震驚了整個(gè)濱河市煞聪,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌逝慧,老刑警劉巖昔脯,帶你破解...
    沈念sama閱讀 217,185評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異笛臣,居然都是意外死亡云稚,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門沈堡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)静陈,“玉大人,你說(shuō)我怎么就攤上這事诞丽【ㄓ担” “怎么了?”我有些...
    開封第一講書人閱讀 163,524評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵僧免,是天一觀的道長(zhǎng)刑赶。 經(jīng)常有香客問(wèn)我,道長(zhǎng)懂衩,這世上最難降的妖魔是什么撞叨? 我笑而不...
    開封第一講書人閱讀 58,339評(píng)論 1 293
  • 正文 為了忘掉前任金踪,我火速辦了婚禮,結(jié)果婚禮上谒所,老公的妹妹穿的比我還像新娘热康。我一直安慰自己,他們只是感情好劣领,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評(píng)論 6 391
  • 文/花漫 我一把揭開白布姐军。 她就那樣靜靜地躺著,像睡著了一般尖淘。 火紅的嫁衣襯著肌膚如雪奕锌。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,287評(píng)論 1 301
  • 那天村生,我揣著相機(jī)與錄音惊暴,去河邊找鬼。 笑死趁桃,一個(gè)胖子當(dāng)著我的面吹牛辽话,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播卫病,決...
    沈念sama閱讀 40,130評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼油啤,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了蟀苛?” 一聲冷哼從身側(cè)響起益咬,我...
    開封第一講書人閱讀 38,985評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎帜平,沒(méi)想到半個(gè)月后幽告,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡裆甩,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評(píng)論 3 334
  • 正文 我和宋清朗相戀三年冗锁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嗤栓。...
    茶點(diǎn)故事閱讀 39,779評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蒿讥,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出抛腕,到底是詐尸還是另有隱情芋绸,我是刑警寧澤,帶...
    沈念sama閱讀 35,477評(píng)論 5 345
  • 正文 年R本政府宣布担敌,位于F島的核電站摔敛,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏全封。R本人自食惡果不足惜马昙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評(píng)論 3 328
  • 文/蒙蒙 一桃犬、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧行楞,春花似錦攒暇、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至证杭,卻和暖如春田度,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背解愤。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工镇饺, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人送讲。 一個(gè)月前我還...
    沈念sama閱讀 47,876評(píng)論 2 370
  • 正文 我出身青樓奸笤,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親哼鬓。 傳聞我的和親對(duì)象是個(gè)殘疾皇子揭保,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容