開始之前先看效果 前邊為網易雲的效果 後邊為我實現的效果
質量有所壓縮,具體可去下載網易雲音樂自行檢視效果
分析
- 目測佈局:分為兩個viewpager,上面展示文字的viewpager和下面的圖片viewpager;
- 進一步觀察:上面的文字viewpager滑動有延遲,而圖片viewpager是沒有滑動自帶動畫的,而且都沒有自帶滑動手勢效果;
- 分析得出:兩個viewpager都攔截滑動事件,文字viewpager需要設定切換時間,有動畫效果,圖片viewpager去掉自帶動畫;
- 分析圖片viewpager動畫效果,都是兩張圖片,一張背景,一張上浮圖片;開啟之後,背景:透明度由0到1;上浮圖片:由下往上冒出;第三張圖片,頭像上浮之外還有個變小的過程
分析完畢,接下來具體實現
實現
- 先實現viewpager滑動攔截,攔截點選事件就行,具體看程式碼不多說
public class MyInterceptViewPager extends ViewPager {
private boolean isScrollable = true;
public MyInterceptViewPager(Context context) {
super(context);
}
public MyInterceptViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
return isScrollable && super.onTouchEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return isScrollable && super.onInterceptTouchEvent(ev);
}
@Override
public void setCurrentItem(int item) {
super.setCurrentItem(item, false);//表示切換的時候,不需要切換時間。
}
@Override
public void setCurrentItem(int item, boolean smoothScroll) {
super.setCurrentItem(item, smoothScroll);
}
}
複製程式碼
- 通過反射,實現viewpager切換動畫速度修改,新建一個類繼承於Scroller
public class FixedSpeedScroller extends Scroller {
private int mDuration = 1500;
public FixedSpeedScroller(Context context) {
super(context);
}
public FixedSpeedScroller(Context context, Interpolator interpolator) {
super(context, interpolator);
}
@Override
public void startScroll(int startX, int startY, int dx, int dy, int duration) {
// Ignore received duration, use fixed one instead
super.startScroll(startX, startY, dx, dy, mDuration);
}
@Override
public void startScroll(int startX, int startY, int dx, int dy) {
// Ignore received duration, use fixed one instead
super.startScroll(startX, startY, dx, dy, mDuration);
}
public void setmDuration(int time) {
mDuration = time;
}
public int getmDuration() {
return mDuration;
}
}
複製程式碼
- 具體使用
try {
Field field = ViewPager.class.getDeclaredField("mScroller");
field.setAccessible(true);
FixedSpeedScroller scrollerText = new FixedSpeedScroller(this, new AccelerateInterpolator());
field.set(mTextViewPager, scrollerText);
scrollerText.setmDuration(400);
} catch (Exception e) {
}
複製程式碼
- 實現兩個viewpager的聯動,根據橫向滑動距離和方向判斷是否應該翻頁
mTouchLayout.setOnTouchListener(new View.OnTouchListener() {
float startX;
float startY;//沒有用到
float endX;
float endY;//沒有用到
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startX = event.getX();
startY = event.getY();
break;
case MotionEvent.ACTION_UP:
endX = event.getX();
endY = event.getY();
WindowManager windowManager = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
Point size = new Point();
windowManager.getDefaultDisplay().getSize(size);
int width = size.x;
if (startX - endX >= (width / 8)){// startX - endX 大於0 且大於寬的1/8 可以往後翻頁
if (pageIndex == 0){
mImageViewPager.setCurrentItem(1);
mTextPager.setCurrentItem(1, true);
}else if (pageIndex == 1){
mImageViewPager.setCurrentItem(2);
mTextPager.setCurrentItem(2, true);
}
}else if (endX - startX >= (width / 8)){ // endX - startX 大於0 且大於寬的1/8 可以往前翻頁
if (pageIndex == 2){
mImageViewPager.setCurrentItem(1);
mTextPager.setCurrentItem(1, true);
}else if (pageIndex == 1){
mImageViewPager.setCurrentItem(0);
mTextPager.setCurrentItem(0, true);
}
}
break;
}
return true;
}
});
複製程式碼
最後
- 本demo資源來自解壓網易雲音樂apk,因為喜歡,所以模仿。
- 本demo github地址Music163GuideDemo如果能點個star,感激不盡
- 如果本demo對你有幫助,來個共贏的事吧,掃個紅包也沒損失↓↓↓