Android仿材料设计实现京东上推隐藏头部

Android仿材料设计实现京东上推隐藏头部

最近写的一个项目的实现类似于京东商品的展示,不bb先上图

  • 动画
  • 事件拦截
  • 对滑动的监听

动画

我这里是主要是使用了两个动画ObjectAnimator,就是让绿色区域上去,然后让下面的区域上来,注意这里有几点:

1.当我们下面滑动视图的第一个条目没有显示时,不让绿色出来;
2.当绿色的出来时,我们向上滑动滚动视图时就要让绿色上去,滑动区域也上来。

我这里加入了上拉加载和下拉刷新,所以也要注意两点:

1.当滚动试图的第一个条目可见且绿色可见是,下滑的事件给包裹的刷新控件;
2.当滚动的视图的第一个条码不可见且绿色不可见时,下滑的事件还是给滑动控件处理;

这里我使用的滑动控件是RecyclerView,因人而异

Android仿材料设计实现京东上推隐藏头部_第1张图片

布局

注意这里的下拉刷新上拉加载(我的小伙伴使用的02年的一个控件)我吓得眼泪都掉下来了,但是由于是属于app开源sdk多个项目在改,所以我只有在原有基础是改,大家可以使用新的,用过的应该比较清楚。


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <RelativeLayout
        android:id="@+id/rl_title"
        android:layout_width="match_parent"
        android:layout_height="150dp"
        android:background="@color/color_24cf5f">

        <TextView
            android:id="@+id/tv_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:text="我的积分" />

        <TextView
            android:id="@+id/tv_num"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/tv_title"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="10dp"
            android:text="2.00" />
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:layout_below="@+id/tv_num"
            android:orientation="horizontal"
            >
            <LinearLayout
                android:layout_width="wrap_content"
                android:background="@drawable/lb_hslib_shape_integralmall"
                android:paddingTop="2dp"
                android:paddingBottom="2dp"
                android:paddingLeft="10dp"
                android:paddingRight="10dp"
                android:id="@+id/ll_jfcj"
                android:layout_marginRight="20dp"
                android:layout_height="wrap_content">
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="积分抽奖"/>
            LinearLayout>
            <LinearLayout
                android:layout_width="wrap_content"
                android:background="@drawable/lb_hslib_shape_integralmall"
                android:paddingTop="2dp"
                android:paddingBottom="2dp"
                android:paddingLeft="10dp"
                android:paddingRight="10dp"
                android:id="@+id/ll_zqjf"
                android:layout_height="wrap_content">
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="赚取积分"/>
            LinearLayout>
        LinearLayout>
    RelativeLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:orientation="vertical"
        android:id="@+id/ll_content"
        android:layout_height="match_parent">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:orientation="horizontal">
            <TextView
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="center"
                android:id="@+id/tv_fenlei"
                android:text="分类"/>
            <TextView
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="center"
                android:id="@+id/tv_redian"
                android:text="热点"/>
        LinearLayout>
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1">
            <commonlib.view.AbPullToRefreshView
                android:id="@+id/act_integramall_ablv"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical">

                <commonlib.view.HsTopRecyclerView
                    android:id="@+id/act_integramall_recyclerview"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:scrollbars="none" />

                <commonlib.view.EmptyLayout
                    android:id="@+id/act_integramall_error_layout"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:background="@color/color_ffffff"
                    android:visibility="gone" />

            commonlib.view.AbPullToRefreshView>
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:id="@+id/ll_masking"
                android:orientation="vertical"
                android:visibility="gone"
                android:clickable="true"
                android:background="#66000000"/>
        RelativeLayout>
    LinearLayout>
LinearLayout>

刷新控件

这是那个刷新控件(不需要可以忽略)
public class AbPullToRefreshView extends LinearLayout {

    /**
     * 日志标记.
     */
    private static final String TAG = "AbPullToRefreshView";

    /**
     * 上下文.
     */
    private Context mContext = null;

    /**
     * 下拉刷新的开关.
     */
    private boolean mEnablePullRefresh = true;

    /**
     * 加载更多的开关.
     */
    private boolean mEnableLoadMore = true;

    /**
     * y上一次保存的.
     */
    private int mLastMotionY;

    /**
     * header view.
     */
    private AbListViewHeader mHeaderView;

    /**
     * footer view.
     */
    private AbListViewFooter mFooterView;

    /**
     * list or grid.
     */
    private AdapterView mAdapterView;

    /**
     * 是否允许在list或grid模式下没有子项时刷新和加载
     */
    private boolean mEnablePullAndLoadWithNoChild = true;

    /**
     * Scrollview.
     */
    private ScrollView mScrollView;

    /**
     * RecyclerView.
     */
    private RecyclerView mRecyclerView;

    /**
     * 对recyclerview上的头部视图的拦截
     * 见HsIntegralMallActivity界面
     */

    private boolean topVisibility=true;
    /**
     * header view 高度.
     */
    private int mHeaderViewHeight;

    /**
     * footer view 高度.
     */
    private int mFooterViewHeight;

    /**
     * 滑动状态.
     */
    private int mPullState;

    /**
     * 上滑动作.
     */
    private static final int PULL_UP_STATE = 0;

    /**
     * 下拉动作.
     */
    private static final int PULL_DOWN_STATE = 1;

    /**
     * 上一次的数量.
     */
    private int mCount = 0;

    /**
     * 是否还有数据.
     */
    private boolean isAll = false;

    /**
     * 正在下拉刷新.
     */
    public boolean mPullRefreshing = false;

    /**
     * 正在加载更多.
     */
    public boolean mPullLoading = false;

    /**
     * Footer加载更多监听器.
     */
    private OnFooterLoadListener mOnFooterLoadListener;

    /**
     * Header下拉刷新监听器.
     */
    private OnHeaderRefreshListener mOnHeaderRefreshListener;

    /**
     * 用于控制延时收回Header和Footer
     */
    private Timer mTimer;

    /**
     * UI线程的句柄
     */
    private Handler mHandler;

    /**
     * 构造.
     *
     * @param context the context
     * @param attrs   the attrs
     */
    public AbPullToRefreshView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    /**
     * 构造.
     *
     * @param context the context
     */
    public AbPullToRefreshView(Context context) {
        super(context);
        init(context);
    }

    /**
     * 初始化View.
     *
     * @param context the context
     */
    private void init(Context context) {
        mContext = context;

        mHandler = new Handler(context.getMainLooper());
        mTimer = new Timer();

        // 增加HeaderView
        addHeaderView();
    }

    /**
     * add HeaderView.
     */
    private void addHeaderView() {
        mHeaderView = new AbListViewHeader(mContext);
        mHeaderViewHeight = mHeaderView.getHeaderHeight();
        mHeaderView.setGravity(Gravity.BOTTOM);
//        mHeaderView.setBackgroundColor(Color.TRANSPARENT);

        LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,
                mHeaderViewHeight);
        // 设置topMargin的值为负的header View高度,即将其隐藏在最上方
        params.topMargin = -(mHeaderViewHeight);
        addView(mHeaderView, params);

    }

    /**
     * add FooterView.
     */
    private void addFooterView() {

        mFooterView = new AbListViewFooter(mContext);
        mFooterViewHeight = mFooterView.getFooterHeight();
//        mFooterView.setBackgroundColor(Color.TRANSPARENT);

        LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,
                mFooterViewHeight);
        addView(mFooterView, params);
    }

    /**
     * 在此添加footer view保证添加到linearlayout中的最后.
     */
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        addFooterView();
        initContentAdapterView();
    }

    /**
     * init AdapterView like ListView, GridView and so on; or init ScrollView.
     */
    private void initContentAdapterView() {
        int count = getChildCount();
        if (count < 3) {
            throw new IllegalArgumentException(
                    "this layout must contain 3 child views,and AdapterView or ScrollView must in the second position!");
        }
        View view = null;
        for (int i = 0; i < count - 1; ++i) {
            view = getChildAt(i);
            if (view instanceof AdapterView) {
                mAdapterView = (AdapterView) view;
            }
            if (view instanceof ScrollView) {
                // finish later
                mScrollView = (ScrollView) view;
            }
            if(view instanceof RecyclerView){
                mRecyclerView= (RecyclerView) view;
            }
        }
        if (mAdapterView == null && mScrollView == null&&mRecyclerView==null) {
            throw new IllegalArgumentException(
                    "must contain a AdapterView or ScrollView in this layout!");
        }
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * android.view.ViewGroup#onInterceptTouchEvent(android.view.MotionEvent)
     */
    @Override
    public boolean onInterceptTouchEvent(MotionEvent e) {
        int y = (int) e.getRawY();
        switch (e.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // 首先拦截down事件,记录y坐标
                mLastMotionY = y;
                break;
            case MotionEvent.ACTION_MOVE:
                // deltaY > 0 是向下运动,< 0是向上运动
                int deltaY = y - mLastMotionY;
                if (isRefreshViewScroll(deltaY)) {
                    return true;
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                break;
        }
        return false;
    }

    /*
     * 如果在onInterceptTouchEvent()方法中没有拦截(即onInterceptTouchEvent()方法中 return
     * false)则由PullToRefreshView 的子View来处理;否则由下面的方法来处理(即由PullToRefreshView自己来处理)
     */
    /*
     * (non-Javadoc)
     * 
     * @see android.view.View#onTouchEvent(android.view.MotionEvent)
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {

        int y = (int) event.getRawY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // onInterceptTouchEvent已经记录 mLastMotionY = y;
                break;
            case MotionEvent.ACTION_MOVE:
                int deltaY = y - mLastMotionY;
                if (mPullState == PULL_DOWN_STATE) {
                    // 执行下拉
                    headerPrepareToRefresh(deltaY);
                } else if (mPullState == PULL_UP_STATE) {
                    // 执行上拉
                    footerPrepareToRefresh(deltaY);
                }
                mLastMotionY = y;
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                int topMargin = getHeaderTopMargin();
                if (mPullState == PULL_DOWN_STATE) {
                    if (topMargin >= 0) {
                        // 开始刷新
                        headerRefreshing();
                    } else {
                        // 还没有执行刷新,重新隐藏
                        setHeaderTopMargin(-mHeaderViewHeight);
                    }
                } else if (mPullState == PULL_UP_STATE) {
                    if (Math.abs(topMargin) >= mHeaderViewHeight
                            + mFooterViewHeight) {
                        // 开始执行footer 刷新
                        footerLoading();
                    } else {
                        // 还没有执行刷新,重新隐藏
                        setHeaderTopMargin(-mHeaderViewHeight);
                    }
                }
                break;
        }
        return super.onTouchEvent(event);
    }

    /**
     * 判断滑动方向,和是否响应事件.
     *
     * @param deltaY deltaY > 0 是向下运动,< 0是向上运动
     * @return true, if is refresh view scroll
     */
    private boolean isRefreshViewScroll(int deltaY) {

        if (mPullRefreshing || mPullLoading) {
            return false;
        }
        // 对于ListView和GridView
        if (mAdapterView != null) {
            // 子view(ListView or GridView)滑动到最顶端
            if (deltaY > 0) {
                // 判断是否禁用下拉刷新操作
                if (!mEnablePullRefresh) {
                    return false;
                }
                View child = mAdapterView.getChildAt(0);
                if (!mEnablePullAndLoadWithNoChild && child == null) {
                    // 如果mAdapterView中没有数据,不拦截
                    return false;
                }
                if (child == null)
                    child = mAdapterView;
                if (mAdapterView.getFirstVisiblePosition() == 0
                        && child.getTop() == 0) {
                    mPullState = PULL_DOWN_STATE;
                    return true;
                }
                int top = child.getTop();
                int padding = mAdapterView.getPaddingTop();
                if (mAdapterView.getFirstVisiblePosition() == 0
                        && Math.abs(top - padding) <= 11) {// 这里之前用3可以判断,但现在不行,还没找到原因
                    mPullState = PULL_DOWN_STATE;
                    return true;
                }

            } else if (deltaY < -10) {
                // 判断是否禁用上拉加载更多操作
                if (!mEnableLoadMore) {
                    return false;
                }
                View lastChild = mAdapterView.getChildAt(mAdapterView
                        .getChildCount() - 1);
                if (lastChild == null) {
                    // 如果mAdapterView中没有数据,不拦截
                    return false;
                }
                // 最后一个子view的Bottom小于父View的高度说明mAdapterView的数据没有填满父view,
                // 等于父View的高度说明mAdapterView已经滑动到最后
                if (lastChild.getBottom() <= getHeight()
                        && mAdapterView.getLastVisiblePosition() == mAdapterView
                        .getCount() - 1) {
                    mPullState = PULL_UP_STATE;
                    return true;
                }
            }
        }
        // 对于ScrollView
        if (mScrollView != null) {

            // 子scroll view滑动到最顶端
            View child = mScrollView.getChildAt(0);
            if (deltaY > 0 && mScrollView.getScrollY() == 0) {
                mPullState = PULL_DOWN_STATE;
                // 判断是否禁用下拉刷新操作
                return mEnablePullRefresh;
            } else if (deltaY < 0
                    && child.getMeasuredHeight() <= getHeight()
                    + mScrollView.getScrollY()) {
                // 判断是否禁用上拉加载更多操作
                if (!mEnableLoadMore) {
                    return false;
                }
                mPullState = PULL_UP_STATE;
                return true;
            }
        }
        if(mRecyclerView!=null){
            LinearLayoutManager manager= (LinearLayoutManager) mRecyclerView.getLayoutManager();
            if (deltaY > 0) {
                // 判断是否禁用下拉刷新操作
                if (!mEnablePullRefresh) {
                    return false;
                }
                if(!topVisibility){
                    return false;
                }
                View child = mRecyclerView.getChildAt(0);
                if (!mEnablePullAndLoadWithNoChild && child == null) {
                    // 如果mAdapterView中没有数据,不拦截
                    return false;
                }

                if (manager.findFirstCompletelyVisibleItemPosition() == 0) {
                    mPullState = PULL_DOWN_STATE;
                    return true;
                }

            }else if (deltaY < -10) {
            // 判断是否禁用上拉加载更多操作
                if (!mEnableLoadMore) {
                    return false;
                }
                View lastChild = mRecyclerView.getChildAt(mRecyclerView
                        .getChildCount() - 1);
                if (lastChild == null) {
                    // 如果mAdapterView中没有数据,不拦截
                    return false;
                }
                if (mRecyclerView.computeVerticalScrollExtent() + mRecyclerView.computeVerticalScrollOffset()
                        >= mRecyclerView.computeVerticalScrollRange()){
                    mPullState = PULL_UP_STATE;
                    return true;
                }
            }
        }

        return false;
    }

    /**
     * header 准备刷新,手指移动过程,还没有释放.
     *
     * @param deltaY 手指滑动的距离
     */
    private void headerPrepareToRefresh(int deltaY) {
        if (mPullRefreshing || mPullLoading) {
            return;
        }

        int newTopMargin = updateHeaderViewTopMargin(deltaY);
        // 当header view的topMargin>=0时,说明header view完全显示出来了 ,修改header view 的提示状态
        if (newTopMargin >= 0
                && mHeaderView.getState() != AbListViewHeader.STATE_REFRESHING) {
            // 提示松开刷新
            mHeaderView.setState(AbListViewHeader.STATE_READY);

        } else if (newTopMargin < 0 && newTopMargin > -mHeaderViewHeight) {
            // 提示下拉刷新
            mHeaderView.setState(AbListViewHeader.STATE_NORMAL);
        }
    }

    /**
     * footer 准备刷新,手指移动过程,还没有释放 移动footer view高度同样和移动header view
     * 高度是一样,都是通过修改header view的topmargin的值来达到.
     *
     * @param deltaY 手指滑动的距离
     */
    private void footerPrepareToRefresh(int deltaY) {
        if (mPullRefreshing || mPullLoading) {
            return;
        }
        int newTopMargin = updateHeaderViewTopMargin(deltaY);
        // 如果header view topMargin 的绝对值大于或等于header + footer 的高度
        // 说明footer view 完全显示出来了,修改footer view 的提示状态
        if (Math.abs(newTopMargin) >= (mHeaderViewHeight + mFooterViewHeight)
                && mFooterView.getState() != AbListViewFooter.STATE_LOADING) {
            mFooterView.setState(AbListViewFooter.STATE_READY);
        } else if (Math.abs(newTopMargin) < (mHeaderViewHeight + mFooterViewHeight)) {
            mFooterView.setState(AbListViewFooter.STATE_LOADING);
        }
    }

    /**
     * 修改Header view top margin的值.
     *
     * @param deltaY the delta y
     * @return the int
     */
    private int updateHeaderViewTopMargin(int deltaY) {
        LayoutParams params = (LayoutParams) mHeaderView.getLayoutParams();
        float newTopMargin = params.topMargin + deltaY * 0.3f;
        // 这里对上拉做一下限制,因为当前上拉后然后不释放手指直接下拉,会把下拉刷新给触发了
        // 表示如果是在上拉后一段距离,然后直接下拉
        if (deltaY > 0 && mPullState == PULL_UP_STATE
                && Math.abs(params.topMargin) <= mHeaderViewHeight) {
            return params.topMargin;
        }
        // 同样地,对下拉做一下限制,避免出现跟上拉操作时一样的bug
        if (deltaY < 0 && mPullState == PULL_DOWN_STATE
                && Math.abs(params.topMargin) >= mHeaderViewHeight) {
            return params.topMargin;
        }
        params.topMargin = (int) newTopMargin;
        mHeaderView.setLayoutParams(params);
        invalidate();
        return params.topMargin;
    }

    /**
     * 下拉刷新.
     */
    public void headerRefreshing() {
        mPullRefreshing = true;
        mHeaderView.setState(AbListViewHeader.STATE_REFRESHING);
        setHeaderTopMargin(0);
        if (mOnHeaderRefreshListener != null) {

            // lzd 网络判断
            if (AbAppUtil.isNetworkAvailable()) {
                mOnHeaderRefreshListener.onHeaderRefresh(this);
            } else {
                onHeaderRefreshFinish();
                ToastUtils.showToast(HstationInstance.C().getString(R.string.lianbi_hslib_netfail_refresh));
            }

        }
    }

    /**
     * 加载更多.
     */
    private void footerLoading() {
        mPullLoading = true;
        int top = mHeaderViewHeight + mFooterViewHeight;
        setHeaderTopMargin(-top);
        if (mOnFooterLoadListener != null) {
            // lzd 网络判断
            if (AbAppUtil.isNetworkAvailable()) {
                mOnFooterLoadListener.onFooterLoad(this);
            } else {
                onFooterLoadFinish(true);
                ToastUtils.showToast(HstationInstance.C().getString(R.string.lianbi_hslib_netfail_refresh));
            }
        }
    }

    /**
     * 设置header view 的topMargin的值.
     *
     * @param topMargin the new header top margin
     */
    private void setHeaderTopMargin(int topMargin) {
        LayoutParams params = (LayoutParams) mHeaderView.getLayoutParams();
        params.topMargin = topMargin;
        mHeaderView.setLayoutParams(params);
        invalidate();
    }

    /**
     * header view 完成更新后恢复初始状态.
     */
    public void onHeaderRefreshFinish() {
        setHeaderTopMargin(-mHeaderViewHeight);
        mHeaderView.setState(AbListViewHeader.STATE_READY);
        if (mAdapterView != null) {
            mCount = mAdapterView.getCount();
            // 判断有没有数据
            if (mCount > 0) {
                mFooterView.setState(AbListViewFooter.STATE_READY);
            } else {
                mFooterView.setState(AbListViewFooter.STATE_EMPTY);
            }
        } else {
            mFooterView.setState(AbListViewFooter.STATE_READY);
        }
        mPullRefreshing = false;
    }

    /**
     * footer view 完成更新后恢复初始状态.
     */
    public void onFooterLoadFinish() {
        setHeaderTopMargin(-mHeaderViewHeight);
        mHeaderView.setState(AbListViewHeader.STATE_NORMAL);
        if (mAdapterView != null) {
            int countNew = mAdapterView.getCount();
            // 判断有没有更多数据了
            if (countNew > mCount) {
                mFooterView.setState(AbListViewFooter.STATE_READY);
                mPullLoading = false;
                mCount = countNew;
            } else {
                mFooterView.setState(AbListViewFooter.STATE_NO);
                int top = mHeaderViewHeight + mFooterViewHeight;
                setHeaderTopMargin(-top);
                mHandler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        setHeaderTopMargin(-mHeaderViewHeight);
                        isAll = true;
                        mPullLoading = false;
                    }
                }, 2000);
            }
        } else {
            mFooterView.setState(AbListViewFooter.STATE_READY);
            mPullLoading = false;
        }
    }



    /**
     *  咨询带广告没有更多数据
     */
    public void setNodata(){
        mFooterView.setState(AbListViewFooter.STATE_NO);
        int top = mHeaderViewHeight + mFooterViewHeight;
        setHeaderTopMargin(-top);
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                setHeaderTopMargin(-mHeaderViewHeight);
                isAll = true;
                mPullLoading = false;
            }
        }, 2000);
    }

    /**
     * footer view 完成更新后恢复初始状态.
     */
    public void onFooterLoadFinish(boolean hasnext) {
        setHeaderTopMargin(-mHeaderViewHeight);
        mHeaderView.setState(AbListViewHeader.STATE_NORMAL);
        if (mAdapterView != null && !hasnext) {
            int countNew = mAdapterView.getCount();
            // 判断有没有更多数据了
            if (countNew > mCount) {
                mFooterView.setState(AbListViewFooter.STATE_READY);
                mPullLoading = false;
                mCount = countNew;
            } else {
                mFooterView.setState(AbListViewFooter.STATE_NO);
                int top = mHeaderViewHeight + mFooterViewHeight;
                setHeaderTopMargin(-top);
                mHandler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        setHeaderTopMargin(-mHeaderViewHeight);
                        isAll = true;
                        mPullLoading = false;
                    }
                }, 2000);
            }
        } else {
            if (!hasnext) {
                mFooterView.setState(AbListViewFooter.STATE_NO);
                int top = mHeaderViewHeight + mFooterViewHeight;
                setHeaderTopMargin(-top);
                mHandler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        setHeaderTopMargin(-mHeaderViewHeight);
                        isAll = true;
                        mPullLoading = false;
                    }
                }, 2000);
            } else {
                mFooterView.setState(AbListViewFooter.STATE_READY);
                mPullLoading = false;
            }
        }
    }

    /**
     * 获取当前header view 的topMargin.
     *
     * @return the header top margin
     */
    private int getHeaderTopMargin() {
        LayoutParams params = (LayoutParams) mHeaderView.getLayoutParams();
        return params.topMargin;
    }

    /**
     * 设置下拉刷新的监听器.
     *
     * @param headerRefreshListener the new on header refresh listener
     */
    public void setOnHeaderRefreshListener(
            OnHeaderRefreshListener headerRefreshListener) {
        mOnHeaderRefreshListener = headerRefreshListener;
    }

    /**
     * 设置加载更多的监听器.
     *
     * @param footerLoadListener the new on footer load listener
     */
    public void setOnFooterLoadListener(OnFooterLoadListener footerLoadListener) {
        mOnFooterLoadListener = footerLoadListener;
    }

    /**
     * 打开或者关闭下拉刷新功能.
     *
     * @param enable 开关标记
     */
    public void setPullRefreshEnable(boolean enable) {
        mEnablePullRefresh = enable;
    }

    /**
     * 打开或者关闭加载更多功能.
     *
     * @param enable 开关标记
     */
    public void setLoadMoreEnable(boolean enable) {
        mEnableLoadMore = enable;
    }

    /**
     * 下拉刷新是打开的吗.
     *
     * @return true, if is enable pull refresh
     */
    public boolean isEnablePullRefresh() {
        return mEnablePullRefresh;
    }

    /**
     * 加载更多是打开的吗.
     *
     * @return true, if is enable load more
     */
    public boolean isEnableLoadMore() {
        return mEnableLoadMore;
    }

    /**
     * 设置是否允许没有子控件时刷新/加载
     *
     * @param mEnablePullAndLoadWithNoChild
     */
    public void setmEnablePullAndLoadWithNoChild(
            boolean mEnablePullAndLoadWithNoChild) {
        this.mEnablePullAndLoadWithNoChild = mEnablePullAndLoadWithNoChild;
    }

    /**
     * 描述:获取Header View.
     *
     * @return the header view
     */
    public AbListViewHeader getHeaderView() {
        return mHeaderView;
    }

    /**
     * 描述:获取Footer View.
     *
     * @return the footer view
     */
    public AbListViewFooter getFooterView() {
        return mFooterView;
    }

    /**
     * 描述:获取Header ProgressBar,用于设置自定义样式.
     *
     * @return the header progress bar
     */
    public GifView getHeaderProgressBar() {
        return mHeaderView.getHeaderProgressBar();
    }

    /**
     * 描述:获取Footer ProgressBar,用于设置自定义样式.
     *
     * @return the footer progress bar
     */
    public GifView getFooterProgressBar() {
        return mFooterView.getFooterProgressBar();
    }

    public interface OnFooterLoadListener {

        /**
         * On footer load.
         *
         * @param view the view
         */
        void onFooterLoad(AbPullToRefreshView view);
    }

    public interface OnHeaderRefreshListener {

        /**
         * On header refresh.
         *
         * @param view the view
         */
        void onHeaderRefresh(AbPullToRefreshView view);
    }

    /**
     * 对recyclerview上的头部空间可见性的设置
     * @param topVisibility
     */
    public void setTopVisibility(boolean topVisibility) {
        this.topVisibility = topVisibility;
    }
}

RecyclerView

public class HsTopRecyclerView extends RecyclerView {
    private float mpoint,mcurent;
    private TestTouchEvent testTouchEvent;

    public void setTestTouchEvent(TestTouchEvent testTouchEvent) {
        this.testTouchEvent = testTouchEvent;
    }

    public HsTopRecyclerView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onTouchEvent(MotionEvent e) {
        switch (e.getAction()){
            case MotionEvent.ACTION_DOWN:
                mpoint=e.getRawY();
                break;
            case MotionEvent.ACTION_MOVE:
                mcurent=e.getRawY();
                if(mcurent-mpoint>4){
                    if(testTouchEvent!=null){
                        testTouchEvent.event(true);
                    }
                }else {
                    if(testTouchEvent!=null){
                        testTouchEvent.event(false);
                    }
                }
                break;
        }
        return super.onTouchEvent(e);
    }
    public interface TestTouchEvent{
        void event(boolean isDown);
    }
}

Activity

由于有封装,请自由发挥

public class HsIntegralMallActivity extends BaseActivity {
    private AbPullToRefreshView mAddPlatformAblv;
    private HsTopRecyclerView recyclerView;
    private RecyclerView popu_recyclerview;
    private EmptyLayout emptyLayout;
    private RelativeLayout relativeLayout;
    private HsIntegralMallAdapter adapter;
    private LinearLayout ll_content, popu_ll_content, ll_masking,ll_zqjf,ll_jfcj;
    private ObjectAnimator animatorGone, animatorShow, animatorUp, animatorDown;
    private boolean visibility = true;
    private ViewTreeObserver vto;
    private GridLayoutManager layoutManager;
    private int wheight, statusBarHeight1, height;
    private PopupWindow popupWindow;
    private TextView tv_fenlei, tv_redian, tv_title;
    private ArrayList listTest;
    private HsEasyRecyclerAdapterHs popu_adapter;
    private boolean sortClick = false, classClick = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.lb_hslib_integramall_activity);
        initView();
        initEvent();
        initData();
        initData(true);
        initPopuWindow();
    }

    /**
     * 初始化控件
     */
    private void initView() {
        mAddPlatformAblv = findView(R.id.act_integramall_ablv);
        recyclerView = findView(R.id.act_integramall_recyclerview);
        emptyLayout = findView(R.id.act_integramall_error_layout);
        relativeLayout = findView(R.id.rl_title);
        ll_content = findView(R.id.ll_content);
        tv_fenlei = findView(R.id.tv_fenlei);
        tv_redian = findView(R.id.tv_redian);
        tv_title = findView(R.id.tv_title);
        ll_masking = findView(R.id.ll_masking);
        ll_zqjf=findView(R.id.ll_zqjf);
        ll_jfcj=findView(R.id.ll_jfcj);
    }

    /**
     * 初始化监听
     */
    private void initEvent() {
        mAddPlatformAblv.setOnHeaderRefreshListener(new AbPullToRefreshView.OnHeaderRefreshListener() {
            @Override
            public void onHeaderRefresh(AbPullToRefreshView view) {
                initData(true);
            }
        });

        mAddPlatformAblv.setOnFooterLoadListener(new AbPullToRefreshView.OnFooterLoadListener() {
            @Override
            public void onFooterLoad(AbPullToRefreshView view) {
                initData(false);
            }
        });
        vto = relativeLayout.getViewTreeObserver();
        vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                relativeLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                height = relativeLayout.getHeight();
                initAnimator(relativeLayout, ll_content);
            }
        });
        WindowManager wm = this.getWindowManager();
        wheight = wm.getDefaultDisplay().getHeight();

        statusBarHeight1 = -1;
        //获取status_bar_height资源的ID
        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            //根据资源ID获取响应的尺寸值
            statusBarHeight1 = getResources().getDimensionPixelSize(resourceId);
        }
        mAddPlatformAblv.setLoadMoreEnable(true);
        mAddPlatformAblv.setPullRefreshEnable(true);
        recyclerView.setTestTouchEvent(new HsTopRecyclerView.TestTouchEvent() {
            @Override
            public void event(boolean isDown) {
                if (isDown && layoutManager.findFirstCompletelyVisibleItemPosition() == 0 && !visibility) {
                    if (!animatorShow.isRunning() && !animatorDown.isRunning() && !animatorGone.isRunning() && !animatorUp.isRunning()) {
                        animatorShow.start();
                        animatorDown.start();
                    }
                } else if (!isDown && visibility && !animatorGone.isRunning() && !animatorUp.isRunning() && !animatorShow.isRunning() && !animatorDown.isRunning()) {
                    animatorGone.start();
                    animatorUp.start();
                }
            }
        });
        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                    //不可以下滚
                    if (!recyclerView.canScrollVertically(-1) && !visibility) {
                        animatorShow.start();
                        animatorDown.start();
                    }
                }
            }
        });
        tv_fenlei.setOnClickListener(this);
        tv_redian.setOnClickListener(this);
        ll_masking.setOnClickListener(this);
        tv_title.setOnClickListener(this);
        ll_zqjf.setOnClickListener(this);
        ll_jfcj.setOnClickListener(this);
    }

    @Override
    protected void onChildClick(View view) {
        super.onChildClick(view);
        Intent intent;
        if (view == tv_fenlei) {
            if (classClick) {
                popupWindow.dismiss();
                classClick=false;
            }else {
                if (popupWindow.isShowing()) {
                    initPopuData(0);
                    sortClick=false;
                }
                if (!popupWindow.isShowing()) {
                    initPopuData(0);
                    popupWindow.showAsDropDown(view);
                    ll_masking.setVisibility(View.VISIBLE);
                }
                classClick=true;
            }

        } else if (view == tv_redian) {
            if(sortClick){
                popupWindow.dismiss();
                sortClick=false;
            }else {
                if (popupWindow.isShowing()) {
                    initPopuData(1);
                    classClick=false;
                }
                if (!popupWindow.isShowing()) {
                    initPopuData(1);
                    popupWindow.showAsDropDown(view);
                    ll_masking.setVisibility(View.VISIBLE);
                }
                sortClick=true;
            }

        } else if (view == ll_masking) {
            popupWindow.dismiss();
        } else if (view == tv_title) {
            intent=new Intent();
            intent.setClass(getWeakContext(),HsWinningRecordingActivity.class);
            startActivity(intent);
        }else if(view==ll_zqjf){
            intent=new Intent();
            intent.setClass(getWeakContext(),HsGetIntegralActivity.class);
            startActivity(intent);
        }else if(view==ll_jfcj){
            intent=new Intent();
            intent.setClass(getWeakContext(),HsLotteryWebActivity.class);
            startActivity(intent);
        }
    }

    /**
     * 初始化动画
     *
     * @param rl
     * @param ll
     */
    public void initAnimator(RelativeLayout rl, LinearLayout ll) {
        animatorGone = ObjectAnimator.ofFloat(rl, "translationY", 0, -height);
        animatorGone.setDuration(200);
        animatorShow = ObjectAnimator.ofFloat(rl, "translationY", -height, 0);
        animatorShow.setDuration(200);
        animatorUp = ObjectAnimator.ofFloat(ll, "translationY", 0, -height);
        animatorUp.setDuration(200);
        animatorDown = ObjectAnimator.ofFloat(ll, "translationY", -height, 0);
        animatorDown.setDuration(200);
        Animator.AnimatorListener listener = new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                visibility = !visibility;
                mAddPlatformAblv.setTopVisibility(visibility);
                if (visibility) {
                    layoutManager.scrollToPositionWithOffset(0, 0);
                }
            }

            @Override
            public void onAnimationCancel(Animator animation) {
            }

            @Override
            public void onAnimationRepeat(Animator animation) {
            }
        };
        animatorShow.addListener(listener);
        animatorGone.addListener(listener);
    }

    /**
     * 初始化数据
     */
    private void initData() {
        ll_content.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, wheight - ScreenUtils.dp2px(getWeakContext(), 48) - statusBarHeight1));
        recyclerView.setLayoutManager(layoutManager = new GridLayoutManager(getWeakContext(), 2));
        adapter = new HsIntegralMallAdapter(getWeakContext());
        popu_adapter = new HsEasyRecyclerAdapterHs(getWeakContext(), R.layout.lb_hslib_integrapopuwindow_item) {
            TextView poputv_title;
            @Override
            public void onBind(HsBaseViewHolder holder, int position) {
                poputv_title = holder.get(R.id.tv_content);
                poputv_title.setText(get(position));
                System.out.println("初始化了");
                poputv_title.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (popupWindow.isShowing()) {
                            popupWindow.dismiss();
                            Toast.makeText(getWeakContext(), "点击了", Toast.LENGTH_SHORT).show();
                        }
                    }
                });
            }
        };
        recyclerView.setAdapter(adapter);
    }

    /**
     * 下载
     *
     * @param isRefresh
     */
    private void initData(boolean isRefresh) {
        ArrayList list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            list.add(new Records());
        }
        adapter.addAll(list);
        AbPullHide.hideRefreshView(isRefresh, mAddPlatformAblv);
    }

    /**
     * 初始化弹窗
     */
    private void initPopuWindow() {
        View view = LayoutInflater.from(getWeakContext()).inflate(R.layout.lb_hslib_integrallmall_popu_layout, null);
        popu_recyclerview = (RecyclerView) view.findViewById(R.id.rv);
        popu_recyclerview.setLayoutManager(new LinearLayoutManager(getWeakContext()));
        popu_recyclerview.setAdapter(popu_adapter);
        popu_ll_content = (LinearLayout) view.findViewById(R.id.ll_content);
        popupWindow = new PopupWindow(view, LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        popupWindow.setBackgroundDrawable(new ColorDrawable(0xffffffff));
        popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
            @Override
            public void onDismiss() {
                ll_masking.setVisibility(View.GONE);
                sortClick=false;
                classClick=false;
            }
        });
    }

    /**
     * 初始化弹窗数据
     */
    private void initPopuData(int type) {
        listTest = new ArrayList<>();
        popu_adapter.clear();
        switch (type) {
            case 0:
                for (int i = 0; i < 7; i++) {
                    listTest.add("测试" + i);
                }
                popu_adapter.addAll(listTest);
                if (listTest.size() > 6) {
                    popu_ll_content.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 300));
                } else {
                    popu_ll_content.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
                }

                break;
            case 1:
                for (int i = 0; i < 2; i++) {
                    listTest.add("测试" + i);
                }
                popu_adapter.addAll(listTest);
                if (listTest.size() > 6) {
                    popu_ll_content.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 300));
                } else {
                    popu_ll_content.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
                }

                break;
        }
    }

}

事件拦截

主要就是对数据以及是否第一个条码可见来判断

 if(mRecyclerView!=null){
            LinearLayoutManager manager= (LinearLayoutManager) mRecyclerView.getLayoutManager();
            if (deltaY > 0) {
                // 判断是否禁用下拉刷新操作
                if (!mEnablePullRefresh) {
                    return false;
                }
                if(!topVisibility){
                    return false;
                }
                View child = mRecyclerView.getChildAt(0);
                if (!mEnablePullAndLoadWithNoChild && child == null) {
                    // 如果mAdapterView中没有数据,不拦截
                    return false;
                }

                if (manager.findFirstCompletelyVisibleItemPosition() == 0) {
                    mPullState = PULL_DOWN_STATE;
                    return true;
                }

            }else if (deltaY < -10) {
            // 判断是否禁用上拉加载更多操作
                if (!mEnableLoadMore) {
                    return false;
                }
                View lastChild = mRecyclerView.getChildAt(mRecyclerView
                        .getChildCount() - 1);
                if (lastChild == null) {
                    // 如果mAdapterView中没有数据,不拦截
                    return false;
                }
                if (mRecyclerView.computeVerticalScrollExtent() + mRecyclerView.computeVerticalScrollOffset()
                        >= mRecyclerView.computeVerticalScrollRange()){
                    mPullState = PULL_UP_STATE;
                    return true;
                }
            }

对滑动的监听

recyclerView.setTestTouchEvent(new HsTopRecyclerView.TestTouchEvent() {
            @Override
            public void event(boolean isDown) {
                if (isDown && layoutManager.findFirstCompletelyVisibleItemPosition() == 0 && !visibility) {
                    if (!animatorShow.isRunning() && !animatorDown.isRunning() && !animatorGone.isRunning() && !animatorUp.isRunning()) {
                        animatorShow.start();
                        animatorDown.start();
                    }
                } else if (!isDown && visibility && !animatorGone.isRunning() && !animatorUp.isRunning() && !animatorShow.isRunning() && !animatorDown.isRunning()) {
                    animatorGone.start();
                    animatorUp.start();
                }
            }
        });
        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                    //不可以下滚
                    if (!recyclerView.canScrollVertically(-1) && !visibility) {
                        animatorShow.start();
                        animatorDown.start();
                    }
                }
            }
        });

效果在最上面,抠脚来的不喜勿喷

你可能感兴趣的:(Androi事件分发)