我們都會遇到這樣的需求就是下方ViewPager 上方一個(gè)導(dǎo)航 導(dǎo)航文字底下還會有個(gè)滑動(dòng)線兄朋。如果是手寫實(shí)現(xiàn)的話 肯定是基于 onpagescroll 方法 來改變滑動(dòng)線的leftmargin 實(shí)現(xiàn)滑動(dòng)線的滑動(dòng)谱姓。
所以下面我就直接分析
我先把核心部分代碼貼出來 然后再給大家分析下為什么這么寫
[html]view plaincopy
viewPager.setOnPageChangeListener(new?ViewPager.OnPageChangeListener()?{
@Override
public?void?onPageScrolled(int?position,?float?offset,?int?positionOffsetPixels)?{
LayoutParamslp=?(LayoutParams)?line
.getLayoutParams();
intlength=tabNames.length;
if(currentIndex==position){
lp.leftMargin=?(int)?(offset?*?(screenWidth?*?1.0?/?length)
+?currentIndex
*?(screenWidth?/?length));
}else?if(currentIndex>position){
lp.leftMargin=?(int)?(-(1?-?offset)
*?(screenWidth?*?1.0?/?length)
+?currentIndex
*?(screenWidth?/?length));
}
line.setLayoutParams(lp);
}
@Override
public?void?onPageSelected(int?position)?{
currentIndex=position;
}
@Override
public?void?onPageScrollStateChanged(int?state)?{
}
});
首先我會分析給大家聽 onPageScrolled 的過程中 position 和 currentindex 的變化
currentindex 每次記錄當(dāng)前頁面的位置 姻蚓。 position 是這里的position不是 onPageSelected的position
由于滑動(dòng)式currentindex 首先是不變的熏矿。 當(dāng)滑動(dòng)超過一半時(shí) currentindex
就會變, 而position會根據(jù)滑動(dòng)方向 泄朴, 當(dāng) 往左滑動(dòng)時(shí) 馬上會減一 蔬顾, 當(dāng)往右滑動(dòng)時(shí)會 先不變。
然后當(dāng)viewpager頁面停止后他才會判斷頁面是否劃過去了 劃過去就加 一 沒有就不變昭齐。
所以 currentindex 永遠(yuǎn)是大于或者等于position的
offset 是一個(gè)小數(shù)從0 變化到1 ?如果從左到右 是 0-1 ?從右到左是 1-0尿招;
基于這個(gè)分析 從左往右 滑動(dòng)時(shí) ?假設(shè)從第0個(gè)頁面滑到 第1個(gè)頁面
首先是 currentindex 與 position 相等。 然后超過一半時(shí) currentindex>posiiton
······(1)當(dāng)currentindex =position 時(shí) 改變 滑動(dòng)線的leftmargin
lp.leftMargin = (int) (offset * (screenWidth * 1.0 / length)
+ currentIndex *(screenWidth / length));
length代表 幾個(gè)tab ?屏幕寬度除以tab個(gè)數(shù)表示每個(gè)滑動(dòng)線的寬度。
這時(shí) 滑動(dòng)線的左側(cè)leftmargin 初始值 肯定是 currentindex*這個(gè)寬度的就谜。
那么當(dāng)變化時(shí)我們就基于這個(gè)初始值 進(jìn)行改變
用寬度*offset 這時(shí)offset 是0-1 的變化 怪蔑。肯定是增長 就是滑動(dòng)線 在往右移動(dòng)
那么當(dāng) 滑動(dòng)過一半時(shí) ?currentindex 變成了 1
(2)currentIndex>position
lp.leftMargin = (int) (-(1 - offset)* (screenWidth * 1.0 / length)
+ currentIndex * (screenWidth / length));
這時(shí) cunrrentindex 增加了一個(gè)丧荐。所以這時(shí)*寬度 相當(dāng)于我們最終 leftmargin 的距離缆瓣。然而我們還沒有到達(dá)
最終的位置 我們剛過一半兒 那我們在往最終位置變化時(shí)offset 是趨近于1 的 而若想要這個(gè)過程leftmargin 在增長
我們就用 1-offset 這個(gè)值是趨近于 0的 那么 ? ? ?(int) (-(1 - offset)* (screenWidth * 1.0 / length) ?計(jì)算的就是我們離最終位置到底差了多少。虹统。
用最終位置 ? ? ? ? currentIndex*(screenWidth / length)); ? 減去上面的就是當(dāng)前位置
這里有些饒 大家多讀讀 多思考下 弓坞。 其實(shí)難點(diǎn)就在這里。
從右往左分析 我就不寫了车荔。 就是一樣的思路昼丑。大家可以自行分析分析。就是利用這個(gè)就可以實(shí)現(xiàn)頂部滑動(dòng)線夸赫。。咖城,