标题滑动隐藏,滑动中背景图标变化,仿淘宝商祥

本文介绍了一种仿照淘宝商品详情页的滑动效果实现方法,包括标题栏渐变透明度及图标切换、图文详情固定及滑动事件接管等关键技术点。
先申明菜鸟一枚,有不对的地方欢迎大神指正。编辑的主要目的是记录下最近做的一些效果。仿淘宝商祥标题下拉滑动时的渐变,滑到详情时详情的标题栏固定不动由详情的内容继续滑动。效果如图:

这里写图片描述
先分两个部分一是滑动的时候改变标题透明度和图标,二是滑动到图文时接管滑动事件。
1.滑动到图文时图文这一行固定
布局这边最外层是RelativeLayout,用于将标题浮于上层。
这里写图片描述
中间LinearLayout里面是嵌套自定义的MyScrollView,代码

public class MyScrollView extends ScrollView {

    private Handler mHandler;

    /**
     * 2017/0713
     */
    public interface ScrollViewListener {

        void onScrollChanged(MyScrollView scrollView, int x, int y,
                             int oldx, int oldy);

    }

    private ScrollViewListener scrollViewListener = null;

    public void setScrollViewListener(ScrollViewListener scrollViewListener) {
        this.scrollViewListener = scrollViewListener;
    }

    /**
     * end
     */
    public MyScrollView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public MyScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyScrollView(Context context) {
        super(context);
    }

    public void setHandler(Handler handler) {
        mHandler = handler;
    }

    public boolean isAtBottom() {

        return getScrollY() == getChildAt(getChildCount() - 1).getBottom()
                + getPaddingBottom()  - getHeight();
    }

    public int getHeihgtToTitle(){
        return  getChildAt(getChildCount() - 1).getBottom()
                + getPaddingBottom()  - getHeight();
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if (mHandler != null) {
            if (isAtBottom()) {
                mHandler.sendEmptyMessage(0);
            } else {
                mHandler.sendEmptyMessage(1);
            }
        }
        if (scrollViewListener != null) {
            scrollViewListener.onScrollChanged(this, l, t, oldl, oldt);
        }
    }
}

主要有两点,一个是通过getScrollY() == getChildAt(getChildCount() - 1).getBottom()+ getPaddingBottom() - getHeight() 来判断图文详情是否滑动到了顶部,通过

if (mHandler != null) {
            if (isAtBottom()) {
                mHandler.sendEmptyMessage(0);
            } else {
                mHandler.sendEmptyMessage(1);
            }
        }

来发消息,并在activity中处理:

    ((MyScrollView) mScrollView).setHandler(new Handler() {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                if (msg.what == 0) {
                    if (mDetailFragment != null) {
                        mDetailFragment.scrollToBottom(true);
                        mTab.setVisibility(View.VISIBLE);
                    }
                } else if (msg.what == 1) {
                    if (mDetailFragment != null) {
                        mDetailFragment.scrollToBottom(false);
                        mTab.setVisibility(View.GONE);
                    }
                }
            }
        });

这里mTab指的是
这里写图片描述
当图文详情的fragment滑动到顶部时会在方框处显示一个图文参数评价一样的线性布局盖住之前的图文这一行使其实现固定在标题下边的效果,图文详情实为一个webview,这时候由webview去接管滑动。
.scrollToBottom(true) 方法中在fragment里根据是否滑动到底部来做滑动事件的处理:
这里写图片描述

到这里实现滑到图文时图文这一行固定然后继续滑动webview。
2.滑动时标题变化
自定义ScrollView中返回了onScrollChanged的回调和图文到底部的距离也就是变化的范围是从0 到这个距离的过程中去渐变。

public int getHeihgtToTitle(){
        return  getChildAt(getChildCount() - 1).getBottom()
                + getPaddingBottom()  - getHeight();
    }

有了滑动的范围和监听,就是在activity中去处理过程中的渐变了

@Override
    public void onScrollChanged(MyScrollView scrollView, int x, int y, int oldx, int oldy) {
        int distance = scrollView.getHeihgtToTitle();
        if (y <= 0) {   //设置标题的背景颜色
            mTitleView.setBackgroundResource(R.color.transparent);
            title_pic.setAlpha(0.0f);

            mIbShare.setAlpha(1f);
            mIbShare.setImageResource(R.drawable.image_product_share);

            go_up.setAlpha(1f);
            go_up.setImageResource(R.drawable.image_product_home);

            iv_back.setImageResource(R.drawable.image_product_back);
            iv_back.setAlpha(1f);

        } else if (y > 0 && y <= distance) {
            //滑动距离小于图文的高度时,设置背景颜色透明度渐变
            float scale = (float) y / distance;
            float alpha = (255 * scale);
            mTitleView.setBackgroundColor(Color.argb((int) alpha, 255,255,255));
            title_pic.setAlpha(scale);

            mIbShare.setAlpha(scale);
            mIbShare.setImageResource(R.drawable.image_product_share_selector);

            go_up.setImageResource(R.drawable.image_product_home_selector);
            go_up.setAlpha(scale);

            iv_back.setImageResource(R.drawable.image_product_back_two);
            iv_back.setAlpha(scale);

//          判断到中间区域时改变图片
//          if (((distance/2)-50)< y && y< ((distance/2)+50)){
//              mIbShare.setImageResource(R.drawable.image_product_share_selector);
////                mIbShare.setAlpha((float) 0.0);
////
////                go_up.setAlpha((float) 0.0);
//              go_up.setImageResource(R.drawable.image_product_home_selector);
//
//          }else{
//              mIbShare.setImageResource(R.drawable.image_product_share);
//              go_up.setImageResource(R.drawable.image_product_home);
//          }

//          判断在上半部分显示-->隐藏,先半部分隐藏-->显示
//          if(y < distance/2){
//              float a = (float) y/(distance/2);
//              float scale2 = 1-a;
//              Log.i("apple",a+"---我是小于------");
//              mIbShare.setAlpha(scale2);
//
//              go_up.setAlpha(scale2);
//          }else {
//              float b =(float)(distance/2)/ y;
//              float scale3 = 1-b;
//              Log.i("apple",b+"---我是大于------");
//              mIbShare.setAlpha(scale3);
//
//              go_up.setAlpha(scale3);
//          }

        } else {    //滑动到图文下面设置普通样式
            mTitleView.setBackgroundColor(Color.argb((int) 255, 255,255,255));
            title_pic.setAlpha((float) 1);

            mIbShare.setImageResource(R.drawable.image_product_share_selector);
            mIbShare.setAlpha((float)1);

            iv_back.setImageResource(R.drawable.image_product_back_two);
            iv_back.setAlpha((float) 1);

            go_up.setImageResource(R.drawable.image_product_home_selector);
            go_up.setAlpha((float)1);
        }
    }

可以看到一开始设置标题栏全透明,此时的图标是第一套图,在y > 0 && y <= distance的过程中去逐渐加深标题透明度同时换第二套图。(注释的代码是尝试实现淘宝标题图片在滑动区间的一半的时候第一套图先渐隐,然后第二套图再渐现,我在这个距离的二分之一做判断但是出来的效果并不好这里只能放弃了,有大神实现的希望能学校下)

到这里实现功能,注意点在于渐变范围的获取,图文到顶部的判断和发消息,滑动事件的由scrollview还是webview接管以及滑动过程中的渐变。这里时间问题没有拆出来写个demo以后有时间会补充,主要代码以摘出,欢迎交流。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值