叨叨ViewPager那些事兒(二)

前言

上一篇叨叨ViewPager那些事兒(一)說了一點(diǎn)ViewPager概況球订,這篇打算說說實(shí)際應(yīng)用翻默。


從動(dòng)畫效果說起

先祭上一份谷歌官方的Transformer示例
效果如下


代碼實(shí)現(xiàn)是這樣

public class DepthPageTransformer implements ViewPager.PageTransformer {
    private static final float MIN_SCALE = 0.75f;

    public void transformPage(View view, float position) {
        int pageWidth = view.getWidth();

        if (position < -1) { // [-Infinity,-1)
            // This page is way off-screen to the left.
            view.setAlpha(0);

        } else if (position <= 0) { // [-1,0]
            // Use the default slide transition when moving to the left page
            view.setAlpha(1);
            view.setTranslationX(0);
            view.setScaleX(1);
            view.setScaleY(1);

        } else if (position <= 1) { // (0,1]
            // Fade the page out.
            view.setAlpha(1 - position);

            // Counteract the default slide transition
            view.setTranslationX(pageWidth * -position);

            // Scale the page down (between MIN_SCALE and 1)
            float scaleFactor = MIN_SCALE
                    + (1 - MIN_SCALE) * (1 - Math.abs(position));
            view.setScaleX(scaleFactor);
            view.setScaleY(scaleFactor);

        } else { // (1,+Infinity]
            // This page is way off-screen to the right.
            view.setAlpha(0);
        }
    }
}

乍一看有點(diǎn)懵懂寞埠,一步一問 慢慢來

transformPage(View view, float position)兩個(gè)參數(shù)是何含義


第一個(gè)參數(shù)為各頁卡對象,第二個(gè)是各個(gè)頁卡對于當(dāng)前所展示頁卡的相對位置斥赋,例如璃哟,當(dāng)前頁卡的position為0氛琢,下一張位置為1,前一張則為-1随闪。而ViewPager滑動(dòng)中阳似,position的值是處于平滑變化中的,這就為我們處理動(dòng)畫提供了機(jī)會(huì)铐伴。

撮奏?為何position < -1position > 1時(shí)設(shè)置可見度為0
如前問分析,position < -1position > 1指代頁卡所處區(qū)間為[-Infinity,-1)和(1,+Infinity]当宴,在可見范圍之外畜吊,從節(jié)省繪制資源的角度出發(fā),自然可見度為0即供。

定拟?position (0,1]區(qū)間時(shí)為何要設(shè)置偏移度為(pageWidth * -position)
官方注釋Counteract the default slide transition,抵消頁面滑動(dòng)時(shí)的默認(rèn)偏移量。如頁面處在中間時(shí)偏移量為0*width逗嫡,移至右邊為1*width青自,從中間往右移除時(shí)position0-->1漸變,默認(rèn)偏移量為position*width

驱证?滑動(dòng)動(dòng)畫的縮放效果如何計(jì)算
如效果圖示延窜,當(dāng)下一張頁卡相對位置從1-->0變化時(shí),scale的變化方向?yàn)?code>MIN_SCALE(m)-->1抹锄,不妨列個(gè)公式
(1-position)/(position-0)=(m-scale)/(scale-1)s=(1-position)/(1-position*m)(對逆瑞。。跟示例代碼不一樣伙单。获高。但是效果一樣哦。吻育。
也可以理解為1-scale=|(m-1)|/(1-0)*position念秧,scale從1-->m,位置從0-->1布疼,即每單位position的變化量為|(m-1)|/(1-0)摊趾,乘上position得出變化量币狠。

理論儲(chǔ)備到位之后,自力更生的第一步就是砾层,實(shí)踐漩绵!
下邊我們來寫一個(gè)左右位移,同時(shí)展示三張卡片的動(dòng)畫肛炮,預(yù)想中效果大概是這樣


根據(jù)設(shè)想計(jì)算止吐,左右兩邊的頁卡大小應(yīng)為中間大頁卡的0.9倍,左右頁卡的偏移量約為±0.2倍頁卡寬铸董。
故設(shè)定MIN_Trans_INDEX = 0.2f,MIN_SCALE_INDEX = 0.9f祟印。如上分析,我們只關(guān)心[-1,1]區(qū)間頁卡的動(dòng)畫粟害,
每單位position的scale變化量絕對值為(1-MIN_SCALE_INDEX)/(1-0),即1-scale=|position|*(1-MIN_SCALE_INDEX)/(1-0)scale=1-|position|*(1-MIN_SCALE_INDEX)
同理,每單位position的translationx變化量為pageWidth*(1-MIN_Trans_INDEX)/(1-0),即|0-translationx|=|position|*pageWidth*(1-MIN_Trans_INDEX)|translationx|=|position|*pageWidth*(1-MIN_Trans_INDEX),然而viewpager頁卡滑動(dòng)過程中的默認(rèn)偏移量絕對值為pageWidth * position颤芬,故需在上式基礎(chǔ)上減pageWidth * position悲幅,|translationx|=|position|*pageWidth*MIN_Trans_INDEX
計(jì)算完畢,寫入代碼后發(fā)現(xiàn)站蝠,效果是出來了汰具,但是反應(yīng)好像永遠(yuǎn)。慢半拍菱魔。當(dāng)前頁滑動(dòng)到位后留荔,下一頁才出現(xiàn),體驗(yàn)不太美妙澜倦,如下動(dòng)圖所示

查看代碼后思考聚蝶,應(yīng)該是[-1,1]位置限定導(dǎo)致,左右兩頁分別滑動(dòng)到-1和1時(shí)才開始做動(dòng)畫藻治,而此時(shí)這兩張頁卡已經(jīng)出現(xiàn)在屏幕上碘勉,所以看起來就像“慢了半拍”。
嘗試增加一點(diǎn)“緩沖量”桩卵,改動(dòng)如下

public class MyTransPageTransformer implements ViewPager.PageTransformer {
    private static final float MIN_Trans_INDEX = 0.2f;
    private static final float MIN_SCALE_INDEX = 0.9f;

    @Override
    public void transformPage(@NonNull View page, float position) {
        int pageWidth = page.getWidth();
        if (position < -1.1) { // [-Infinity,-1.1)
            // This page is way off-screen to the left.
            page.setAlpha(0);
        } else if (position <= 0) { // [-1.1,0]
            // Use the default slide transition when moving to the left page
            page.setAlpha(1);
            page.setTranslationX(-pageWidth * position * MIN_Trans_INDEX);
            page.setScaleX((1 - MIN_SCALE_INDEX) * position + 1);
            page.setScaleY((1 - MIN_SCALE_INDEX) * position + 1);
            Log.i("test", page.getTag()+"--"+((1 - MIN_SCALE_INDEX) * position + 1));
        } else if (position <= 1.1) { // (0,1.1]
            // Fade the page out.
            page.setAlpha(1);
            // Counteract the default slide transition
            page.setTranslationX(-pageWidth * position * MIN_Trans_INDEX);
            page.setScaleX(1 - (1 - MIN_SCALE_INDEX) * position);
            page.setScaleY(1 - (1 - MIN_SCALE_INDEX) * position);
        } else { // (1.1,+Infinity]
            // This page is way off-screen to the right.
            page.setAlpha(0);
        }
    }
}

再次運(yùn)行验靡。這才是想要的效果嘛


問題來了

之前遇到過一個(gè)現(xiàn)象,刷新ViewPager雏节,調(diào)用notifyDataSetChanged()胜嗓,如下。

誒钩乍,怎么肥事辞州!左右兩邊的頁卡去哪了!冷靜一下件蚕,刷新時(shí)對當(dāng)前頁卡重繪孙技,若不需滾動(dòng)产禾,則pageoffset始終為0,transformer的動(dòng)畫效果無法顯示牵啦⊙乔椋看來要想平穩(wěn)刷新,還需手動(dòng)更新單條數(shù)據(jù)哈雏。
行動(dòng)起來楞件,更改如下邏輯

@Override
    public void onClick(View v) {
        if (v.getId() == R.id.tv_notify) {
            if (mCurPageIndex == 3) {//測試,代表邏輯需跳轉(zhuǎn)到的頁卡
                isNeedNotify = true;
            }
            //更新當(dāng)前頁卡數(shù)據(jù)
            updateViewPager(mCurPageIndex);
        }
    }
private void updateViewPager(int position) {
        if (isNeedNotify) {//需要滾動(dòng)時(shí)裳瘪,調(diào)用notifyDataSetChanged重走instantiateItem和destroyItem邏輯
            mPagerAdapter.notifyDataSetChanged();
            mViewPager.setCurrentItem(3);
            isNeedNotify = false;
        }
        //僅需更新當(dāng)前頁時(shí)則單獨(dú)刷新當(dāng)前頁卡view
        MyViewPagerItem item = mPageItemList.get(position);
        if (item != null) {
            PageItemBean bean = new PageItemBean();
            bean.num = position;
            bean.tip = mContext.getString(R.string.num_tip, position + 1 + "");
            item.updateUI(bean);
        }
    }

重跑程序土浸,問題解決,Demo先放下彭羹。
為解決問題臨時(shí)想的方案黄伊,是實(shí)現(xiàn)更新的一條思路但感覺不夠優(yōu),歡迎各路大神指點(diǎn)派殷。


最后

本想多寫一點(diǎn)还最,但動(dòng)畫已經(jīng)占了不少篇幅,先在這結(jié)束吧毡惜。這個(gè)系列會(huì)努力補(bǔ)充拓轻,歡迎多多指點(diǎn)和關(guān)注。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末经伙,一起剝皮案震驚了整個(gè)濱河市扶叉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌帕膜,老刑警劉巖枣氧,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異泳叠,居然都是意外死亡作瞄,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進(jìn)店門危纫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宗挥,“玉大人,你說我怎么就攤上這事种蝶∑豕ⅲ” “怎么了?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵螃征,是天一觀的道長搪桂。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么踢械? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任酗电,我火速辦了婚禮,結(jié)果婚禮上内列,老公的妹妹穿的比我還像新娘撵术。我一直安慰自己,他們只是感情好话瞧,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布嫩与。 她就那樣靜靜地躺著,像睡著了一般交排。 火紅的嫁衣襯著肌膚如雪划滋。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天埃篓,我揣著相機(jī)與錄音处坪,去河邊找鬼。 笑死都许,一個(gè)胖子當(dāng)著我的面吹牛稻薇,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播胶征,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼桨仿!你這毒婦竟也來了睛低?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤服傍,失蹤者是張志新(化名)和其女友劉穎钱雷,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體吹零,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡罩抗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了灿椅。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片套蒂。...
    茶點(diǎn)故事閱讀 40,133評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖茫蛹,靈堂內(nèi)的尸體忽然破棺而出操刀,到底是詐尸還是另有隱情,我是刑警寧澤婴洼,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布骨坑,位于F島的核電站,受9級特大地震影響柬采,放射性物質(zhì)發(fā)生泄漏欢唾。R本人自食惡果不足惜且警,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望礁遣。 院中可真熱鬧斑芜,春花似錦、人聲如沸亡脸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽浅碾。三九已至大州,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間垂谢,已是汗流浹背厦画。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留滥朱,地道東北人根暑。 一個(gè)月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像徙邻,于是被迫代替她去往敵國和親排嫌。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評論 2 355

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,183評論 25 707
  • 1缰犁、通過CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請求組件 FMDB本地?cái)?shù)據(jù)庫組件 SD...
    陽明先生_X自主閱讀 15,982評論 3 119
  • 原文鏈接:https://github.com/opendigg/awesome-github-android-u...
    IM魂影閱讀 32,942評論 6 472
  • 人破除自我限制帅容、逐漸改變的過程好比毛毛蟲颇象,雖然過程痛苦然而前景優(yōu)美。 文/ 七彩霞衣 這幾天讀朱光潛先生的《談讀書...
    七彩霞衣閱讀 409評論 1 3
  • 家人們好: 這周有件事情極為震撼了我并徘,讓我覺得這世界上所有的生命都值得尊重遣钳,任何生命體都賦予極高的...
    書_贏閱讀 153評論 0 1