沉沁状态栏 渐变切换图片

忙了一阵终于有点时间了,记录下最近UI上实现的功能
效果如下
这里写图片描述

沉沁状态栏渐变切换图片
一开始想的是用两张imageview去实现这个效果 但是由于app有别的效果还有用两张Imageview的方式判断太复杂.所以就想了另一种方法去实现
这里写图片描述

通过采用两个viewpager联动的方式来达到切换图片渐变的效果 沉沁区的viewpage 暂时命名为 statuViewPage 内容区的viewpage 暂时命名为 contentViewPage; 项目1
首先实现沉沁栏viewpager 堆叠在一起 并且滑动的时候透明度渐变 还好有PageTransformer,所以很轻松的就实现了这个点
/**
 * File description.
 * viewpager 堆叠模式 不可见的view alpha 透明度为0
 * @author lihongjun
 * @date 2018/7/10
 */
public class AlphaTranformer implements ViewPager.PageTransformer {

    @Override
    public void transformPage(@NonNull View page, float position) {
        // 对于屏幕外的不做任何操作
        page.setTranslationX(-position * page.getWidth());
        page.setAlpha(position < -1f || position > 1f ? 0f : 1f - (Math.abs(position)));
    }
}
对于transformPage的position参数的解释不知道可以网上搜索下
把上面的AlphaTranformer设置给statuViewPage就能实现堆叠模式的viewpager了,且切换时带透明度变换
项目2
滑动内容区域的contentViewPage让沉淀statuViewPage联动起来,同过给内容区的contentViewPage设置切换pager监听来实现
1. 当内容区域往左滑动 那么contentViewPage当前页的fragment 透明度从1变到0
contentViewPage的前一个页面从0变到1
2. 内容区域往右滑动 那么contentViewPage当前页的fragment 透明度从1变到0 contentViewPage的后一个页面从0变到1

首先需要知道获取viewpage的切换方向
代码如下

/**
 * Filedescription.
 * viewpage 切换方向监听
 * @author lihongjun
 * @date 2018/8/27
 */
public abstract class OnPageChangeDirectListener implements ViewPager.OnPageChangeListener{

    private int mViewPagerIndex; // 当前viewpage的position
    private int mStartPosition = -1; // 触摸到viewPager第一次滑动时的位置 根据它来判断时左滑还是右滑
    private int mDirect = 0; // 0 向右 1 向左

    private int mNextPosition = -1; // 即滑到页的position
    private float mNextAlpha; // 下一页的alpha

    private boolean mChangeFromScroll = false;// 是否时滑动引起的分页

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        // 如果onpagescroll 是由于点击tab切换引起的则不执行下面的操作
        if (!mChangeFromScroll) {
            return;
        }
        if (mStartPosition == -1) { // 确定方向 得到即将要切换的position
            mStartPosition = position;
            if (mStartPosition == mViewPagerIndex) {
                mDirect = 1;
                mNextPosition = mViewPagerIndex + 1;
                onChangeToNext();
            } else {
                mDirect = 0;
                mNextPosition = mViewPagerIndex - 1;
                onChangeToPre();
            }
        }

        if (mStartPosition == position) { // 只在滑动和未达到切换条件并且返回时的范围内进行alpha变化
            if(positionOffset != 0) { // 不在边界值时改变当前和即将滑到布局的alpha值
                if (mDirect == 0) { // 根据不同的方向来取对应alpha的值 左右滑动对应alpah的值是相反的
                    mNextAlpha = 1.0f - positionOffset;
                } else {
                    mNextAlpha = positionOffset;
                }
                onProgressChange(mNextAlpha);
            }
        }
    }

    @Override
    public void onPageSelected(int position) {
        if(!mChangeFromScroll) {
            onPageScrollStateChanged(SCROLL_STATE_IDLE);
        }
        setWillGoItem(position);
    }

    @Override
    public void onPageScrollStateChanged(int state) {
        if (state == SCROLL_STATE_IDLE) { // 当滚动停止时已经确定当前页是什么
            mViewPagerIndex = getCurrentItem(); // 沉沁栏切换
            mStartPosition = -1; // page 改变时置会初始状态
            mNextPosition = -1;
            mChangeFromScroll = false;
        } else if (state == SCROLL_STATE_DRAGGING) {
            if (!mChangeFromScroll) {
                mChangeFromScroll = true;
            }
        }
    }

    /**
     * 获取下一页的position
     * @return
     */
    public int getNextPosition() {
        return mNextPosition;
    }

    /**
     * 切换到下一页
     */
    public void onChangeToNext() {

    }

    /**
     * 切换到上一页
     */
    public void onChangeToPre() {

    }

    /**
     * 切换进度 next的进度 当前的则为 1 - progess
     * @param progress
     */
    public void onProgressChange(float progress) {

    }

    /**
     * 获取当前页面的 position
     *  @return 当前position
     */
    public abstract int getCurrentItem();

    /**
     * 设置即将跳转过去的item
     * @param position
     */
    public void setWillGoItem(int position) {

    }
}

通过判断 onPageScrolled 中的position变化可以得知 viewpage的切换方向
当positio等于viewpage.getCurrentItem()时表示向右话
否则的话向左滑动

根据滑动方向来动态设置当前页的透明度和即将要切换到的页面的透明度

/**
     * 联动依附的viewpage
     * @param viewPager
     */
    public void setLinkWith(final ViewPager viewPager) {
        if (viewPager != null) {
            viewPager.addOnPageChangeListener(new OnPageChangeDirectListener() {
                @Override
                public int getCurrentItem() {
                    return viewPager.getCurrentItem();
                }

                @Override
                public void setWillGoItem(int position) {
                    if (getAdapter() != null && getAdapter() instanceof MFFragmentStatePageAdapter && getNextPositionByCheck(position) != -1) {
                        setCurrentItem(position);
                    }
                }

                @Override
                public void onProgressChange(float progress) {
                    super.onProgressChange(progress);
                    if (viewPager != null && viewPager.getAdapter() != null && getAdapter() != null && getAdapter() instanceof MFFragmentPagerAdapter
                            && getNextPositionByCheck(getNextPosition()) != -1) { // 若果没有数据则不做任何处理 如果pos位置不合法页也不做任何处理
                        View currentView = null;
                        if (((MFFragmentPagerAdapter)getAdapter()).getCurrentPrimaryItem() != null) {
                            currentView = ((MFFragmentPagerAdapter)getAdapter()).getCurrentPrimaryItem().getView();
                        }
                        View nextView = ((MFFragmentPagerAdapter)getAdapter()).getItemView(getNextPosition());
                        if (currentView != null) {
                            ViewCompat.setAlpha(currentView,1 - progress);
                        }
                        if (nextView != null) {
                            ViewCompat.setAlpha(nextView,progress);
                        }
                    }

                }
            });
        }
    }

通过这样设置就能让两个viewpage联动切换了

关于沉沁栏透明采用的GitHub上的 https://github.com/laobie 来兼容实现的

demo 和lib地址
https://github.com/lhjandroid/LinkStatuViewPage

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值