我們都會遇到這樣的需求就是下方ViewPager 上方一個導航 導航文字底下還會有個滑動線。如果是手寫實現的話 肯定是基於 onpagescroll 方法 來改變滑動線的leftmargin 實現滑動線的滑動。
所以下面我就直接分析
我先把核心部分代碼貼出來 然後再給大家分析下爲什麼這麼寫
<span style="font-size:18px;">viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float offset, int positionOffsetPixels) {
LayoutParams lp = (LayoutParams) line
.getLayoutParams();
int length=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) {
}
});</span>
首先我會分析給大家聽 onPageScrolled 的過程中 position 和 currentindex 的變化
currentindex 每次記錄當前頁面的位置 。 position 是這裏的position不是 onPageSelected的position
由於滑動式currentindex 首先是不變的。 當滑動超過一半時 currentindex
就會變, 而position會根據滑動方向 , 當 往左滑動時 馬上會減一 , 當往右滑動時會 先不變。
然後當viewpager頁面停止後他纔會判斷頁面是否划過去了 划過去就加 一 沒有就不變。
所以 currentindex 永遠是大於或者等於position的
offset 是一個小數從0 變化到1 如果從左到右 是 0-1 從右到左是 1-0;
基於這個分析 從左往右 滑動時 假設從第0個頁面滑到 第1個頁面
首先是 currentindex 與 position 相等。 然後超過一半時 currentindex>posiiton
······(1)當currentindex =position 時 改變 滑動線的leftmargin
lp.leftMargin = (int) (offset * (screenWidth * 1.0 / length)
+ currentIndex *(screenWidth / length));
length代表 幾個tab 屏幕寬度除以tab個數表示每個滑動線的寬度。
這時 滑動線的左側leftmargin 初始值 肯定是 currentindex*這個寬度的。
那麼當變化時我們就基於這個初始值 進行改變
用寬度*offset 這時offset 是0-1 的變化 。肯定是增長 就是滑動線 在往右移動
那麼當 滑動過一半時 currentindex 變成了 1
(2)currentIndex>position
lp.leftMargin = (int) (-(1 - offset)* (screenWidth * 1.0 / length)
+ currentIndex * (screenWidth / length));
這時 cunrrentindex 增加了一個。所以這時*寬度 相當於我們最終 leftmargin 的距離。然而我們還沒有到達
最終的位置 我們剛過一半兒 那我們在往最終位置變化時offset 是趨近於1 的 而若想要這個過程leftmargin 在增長
我們就用 1-offset 這個值是趨近於 0的 那麼 (int) (-(1 - offset)* (screenWidth * 1.0 / length) 計算的就是我們離最終位置到底差了多少。。
用最終位置 currentIndex*(screenWidth / length)); 減去上面的就是當前位置
這裏有些饒 大家多讀讀 多思考下 。 其實難點就在這裏。
從右往左分析 我就不寫了。 就是一樣的思路。大家可以自行分析分析。就是利用這個就可以實現頂部滑動線。。,