高仿小红书引导页实现效果

代码地址如下:
http://www.demodashi.com/demo/11739.html

演示效果

暂时先借用小红帽图片素材的app效果来演示

【暂时先借用小红帽图片素材的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

高仿小红书引导页实现效果

代码地址如下:
http://www.demodashi.com/demo/11739.html

注:本文著作权归作者,由demo大师代发,拒绝转载,转载需要作者授权

posted on 2018-03-05 16:24  demo例子集  阅读(2368)  评论(0编辑  收藏  举报

导航