演示效果
【暫時先借用小紅帽圖片素材的app效果來演示】
文件結構
(1)Android層的代碼實現
(2)實現效果Gif一張
代碼實現過程:
第三方庫
(1)butterknife
通過Gradle引入
(2)viewpagerindicator
通過Model引入
代碼層
(1)在ViewPager的滑動監聽做處理
mNewVp.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
private int lastOffset = -1;
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
Log.d("onPageScrolled參數", "position : " + position + "---" + "positionOffset : " + positionOffset + "---" + "positionOffsetPixels : " + positionOffsetPixels);
//-----------------------------第一部分------------------------------------
if (position == 0) {
settingOne(positionOffset);
} else if (position == 1) {
settingTwo(positionOffset);
} else if (position == 2) {
mHintFragment.startHintAnim();
}
//----------------------------第二部分--------------------------------------
if (lastOffset >= positionOffsetPixels) {
//右滑
Log.d("方向", "右");
} else if (lastOffset < positionOffsetPixels && position == 1) {
//左滑
Log.d("方向", "左");
mHintFragment.endHintAnim();
}
lastOffset = positionOffsetPixels;
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
第一部分
第一部分主要控制各個頁面滑動的效果:
控制第一個頁面
settingOne()
控制第二個頁面
settingTwo()
控制第三個頁面
mHintFragment.startHintAnim();
第三個頁面沒有額外的頭像動畫,只是有個提示的彈出的效果,這是在Fragment中實現的。
settingOne 方法
* 設置第一個界面滑動
*/
private void settingOne(float positionOffset) {
//位移
int[] size = ((NewFragment) fragments.get(0)).getContentSize();
int xMove = (int) (size[0] * 0.53);
int yMove = (int) (size[1] * 0.47);
mAccountIv.setTranslationX(positionOffset * xMove);
mAccountIv.setTranslationY(positionOffset * yMove);
//大小改變
int moveSize = (int) (startSize * 0.4);
ViewGroup.LayoutParams params = mAccountIv.getLayoutParams();
params.width = (int) (dip2px(startSize) - dip2px(moveSize) * positionOffset);
params.height = (int) (dip2px(startSize) - dip2px(moveSize) * positionOffset);
mAccountIv.setLayoutParams(params);
}
這個方法主要是先設置好頭像的滑動空間的比率:
然后通過控制ViewPager的滑動距離,一點一點移動到需要移動的位置。
通過setTranslationX和setTranslationY實現的。
mAccountIv.setTranslationX(positionOffset * xMove);
mAccountIv.setTranslationY(positionOffset * yMove);
而變化大小,則通過改變LayoutParams來實現的
ViewGroup.LayoutParams params = mAccountIv.getLayoutParams();
params.width = (int) (dip2px(startSize) - dip2px(moveSize) * positionOffset);
params.height = (int) (dip2px(startSize) - dip2px(moveSize) * positionOffset);
這里的mAccountIv指的就是頭像。
settingTwo 方法
private void settingTwo(float positionOffset) {
//位移
int[] size = ((NewFragment) fragments.get(1)).getContentSize();
int xMove = (int) (size[0] * 0.53);
int yMove = (int) (size[1] * 0.47);
mAccountIv.setTranslationX(xMove * (1 - positionOffset));
mAccountIv.setTranslationY(yMove * (1 - positionOffset));
//大小改變
int moveSize = (int) (startSize * 0.4);
ViewGroup.LayoutParams params = mAccountIv.getLayoutParams();
params.width = (int) (dip2px(startSize - moveSize) + dip2px(moveSize) * positionOffset);
params.height = (int) (dip2px(startSize - moveSize) + dip2px(moveSize) * positionOffset);
mAccountIv.setLayoutParams(params);
}
這個方法和settingOne類似這里就不做多介紹了。
startHintAnim 方法
這個方法只是做了一個屬性動畫
/**
* 開啟提示動畫
*/
public void startHintAnim() {
if (mHintTv.getX() < 0) {
mHintTv.postDelayed(new Runnable() {
@Override
public void run() {
int width = mHintTv.getWidth();
ValueAnimator animator = ObjectAnimator.ofFloat(mHintTv, "translationX", -width, 0);
animator.setDuration(650);
animator.start();
}
}, 350);
}
}
endHintAnim 方法
/**
* 結束提示動畫
*/
public void endHintAnim() {
if (mHintTv.getX() == 0) {
int width = mHintTv.getWidth();
ValueAnimator animator = ObjectAnimator.ofFloat(mHintTv, "translationX", 0, -width);
animator.setDuration(400);
animator.start();
}
}
項目目錄截圖
備注
剩下具體的實現邏輯在Demo中,可以具體看到。
如果大家在Demo的運行的過程中遇到問題可以聯系我的郵箱:
issuperd@foxmail.com
高仿小紅書引導頁實現效果
注:本文著作權歸作者,由demo大師代發,拒絕轉載,轉載需要作者授權