定义自己的CoorDinatorLayout(NestedScrollingParent)

来源:互联网 发布:网路和网络的区别 编辑:程序博客网 时间:2024/05/16 05:01

先看一张效果图:


先分析一些源码:

CoorDinatorLayout:

public class CoordinatorLayout extends ViewGroup implements NestedScrollingParent


NestedScrollingParent:

    /**     * 引用此接口的条件:     * 1.继承ViewGroup或ViewGroup子类     * 2.子View中包含可以滚动的ChildView(例如:RecyclerView)     */    public interface NestedScrollingParent {        /**         * 列表滚动时首先调用         * nestedScrollAxes用来判断滑动方向:SCROLL_AXIS_HORIZONTAL, SCROLL_AXIS_VERTICAL, SCROLL_AXIS_NONE         * @param child         * @param target         * @param nestedScrollAxes         * @return         */        public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes);        /**         * onStartNestedScroll之后调用         * @param child         * @param target         * @param nestedScrollAxes         */        public void onNestedScrollAccepted(View child, View target, int nestedScrollAxes);        /**         * 滚动停止调用         * @param target         */        public void onStopNestedScroll(View target);        /**         * 滚动之前调用,一般用此方法来消耗滚动         * consumed[0]用来消耗x方法, consumed[1]用来消耗y方法.         * 如果dy或dy未被完全消耗,则传递给剩余部分给滚动View自行处理         * @param target         * @param dx         * @param dy         * @param consumed         */        public void onNestedPreScroll(View target, int dx, int dy, int[] consumed);        /**         *滚动中         * @param target         * @param dxConsumed         * @param dyConsumed         * @param dxUnconsumed         * @param dyUnconsumed         */        public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed);        /**         * 快速滑动前调用         * @param target         * @param velocityX         * @param velocityY         * @return         */        public boolean onNestedPreFling(View target, float velocityX, float velocityY);        /**         * onNestedPreFling之后调用         * @param target         * @param velocityX         * @param velocityY         * @param consumed         * @return         */        public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed);        /**         * 获取当前滚动方向         * @return         */        public int getNestedScrollAxes();    }


测试:

缓慢滑动:

08-23 10:57:13.479 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onStartNestedScroll: 08-23 10:57:13.479 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onNestedScrollAccepted: 08-23 10:57:13.596 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onNestedPreScroll: 08-23 10:57:13.614 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onNestedPreScroll: 08-23 10:57:13.631 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onNestedPreScroll: 08-23 10:57:13.646 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onNestedPreScroll: 08-23 10:57:13.662 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onNestedPreScroll: 08-23 10:57:13.678 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onNestedPreScroll: 08-23 10:57:13.695 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onNestedPreScroll: 08-23 10:57:13.712 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onNestedPreScroll: 08-23 10:57:13.728 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onNestedPreScroll: 08-23 10:57:13.744 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onNestedPreScroll: 08-23 10:57:13.760 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onNestedPreScroll: 08-23 10:57:13.777 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onNestedPreScroll: 08-23 10:57:13.794 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onNestedPreScroll: 08-23 10:57:13.810 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onNestedPreScroll: 08-23 10:57:13.827 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onNestedPreScroll: 08-23 10:57:13.843 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onNestedPreScroll: 08-23 10:57:13.861 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onNestedPreScroll: 08-23 10:57:13.877 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onNestedPreScroll: 08-23 10:57:13.893 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onNestedPreScroll: 08-23 10:57:13.921 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onNestedPreFling: 08-23 10:57:13.921 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onNestedFling: 08-23 10:57:13.923 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onStopNestedScroll: 

快速滑动:

08-23 10:57:56.599 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onStartNestedScroll: 08-23 10:57:56.599 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onNestedScrollAccepted: 08-23 10:57:56.690 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onNestedPreScroll: 08-23 10:57:56.708 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onNestedPreScroll: 08-23 10:57:56.723 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onNestedPreScroll: 08-23 10:57:56.740 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onNestedPreScroll: 08-23 10:57:56.743 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onNestedScroll: 08-23 10:57:56.757 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onNestedPreScroll: 08-23 10:57:56.758 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onNestedScroll: 08-23 10:57:56.774 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onNestedPreScroll: 08-23 10:57:56.776 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onNestedScroll: 08-23 10:57:56.776 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onNestedPreFling: 08-23 10:57:56.776 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onNestedFling: 08-23 10:57:56.778 22139-22139/com.test.git.coordinatorlayout I/ViewParent: onStopNestedScroll: 


下面上Demo源码:

ViewParent:

package com.test.git.coordinatorlayout.Behavior;import android.content.Context;import android.support.v4.view.NestedScrollingParent;import android.support.v4.view.ViewCompat;import android.support.v7.widget.RecyclerView;import android.util.AttributeSet;import android.util.Log;import android.view.View;import android.view.ViewGroup;import android.widget.FrameLayout;import android.widget.OverScroller;/** * Created by lk on 16/8/22. */public class ViewParent extends FrameLayout implements NestedScrollingParent {    private final OverScroller mScroller;    private int mHeaderHeight;    private View viewHeader;    private RecyclerView mRecyclerView;    private static final String TAG = "ViewParent";    public ViewParent(Context context) {        this(context, null);    }    public ViewParent(Context context, AttributeSet attrs) {        super(context, attrs);        mScroller = new OverScroller(context);    }    @Override    protected void onFinishInflate() {        super.onFinishInflate();        for(int i = 0; i < getChildCount(); i ++) {            if(i == 0) {                viewHeader = getChildAt(0);            }else {                View vchild = getChildAt(i);                if(vchild instanceof RecyclerView){                    mRecyclerView = (RecyclerView)vchild;                }            }        }    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        //测量分割栏的高度        getChildAt(1).measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));        ViewGroup.LayoutParams params = mRecyclerView.getLayoutParams();        //设置滚动列表高度        params.height = getMeasuredHeight() - getChildAt(1).getMeasuredHeight();    }    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        //获取头部高度        mHeaderHeight = viewHeader.getMeasuredHeight();    }    @Override    public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) {        Log.i(TAG, "onStartNestedScroll: ");        //判断是否纵向滑动        return (nestedScrollAxes & SCROLL_AXIS_VERTICAL) != 0;    }    @Override    public void onNestedScrollAccepted(View child, View target, int nestedScrollAxes) {        Log.i(TAG, "onNestedScrollAccepted: ");    }    @Override    public void onStopNestedScroll(View target) {        Log.i(TAG, "onStopNestedScroll: ");    }    @Override    public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {        Log.i(TAG, "onNestedScroll: ");    }    @Override    public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) {        Log.i(TAG, "onNestedPreScroll: ");        //dy > 0 向上滑动  getScrollY() < mHeaderHeight 头部未完全隐藏        boolean hide = dy > 0 && getScrollY() < mHeaderHeight;        //dy < 0 向下滑动  getScrollY() >= 0 头部未完全显示        //ViewCompat.canScrollVertically(target, -1)  -1 表示scrolling up, 如果target可以向上滑动返回true, 否则返回false.        boolean show = dy < 0 && getScrollY() >= 0 && !ViewCompat.canScrollVertically(target, -1);        if (show) {//显示            if(getScrollY() + dy < 0){                int sy = - getScrollY();                scrollBy(0, sy);                consumed[1] = sy;            }else {                scrollBy(0, dy);                consumed[1] = dy;            }        }        if(hide){//隐藏            if(dy + getScrollY() > mHeaderHeight){                int sy = mHeaderHeight - getScrollY();                scrollBy(0, sy);                consumed[1] = sy;            }else {                scrollBy(0, dy);                consumed[1] = dy;            }        }    }    @Override    public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed) {        Log.i(TAG, "onNestedFling: ");        return false;    }    @Override    public boolean onNestedPreFling(View target, float velocityX, float velocityY) {        Log.i(TAG, "onNestedPreFling: ");        Log.i(TAG, "onNestedFling: ");        //头部隐藏,则交给滚动列表处理        if(getScrollY() >= mHeaderHeight) {            return false;        }        //滚动        mScroller.fling(0, getScrollY(), 0, (int) velocityY, 0, 0, 0, mHeaderHeight);        invalidate();        return true;    }    @Override    public int getNestedScrollAxes() {        Log.i(TAG, "getNestedScrollAxes: ");        return 0;    }    float a = 0.5f;//视差因子    @Override    public void scrollTo(int x, int y) {        super.scrollTo(x, y);        if(y >= 0 && y <= mHeaderHeight){            viewHeader.scrollTo(0, (int) (- y * a));        }    }    @Override    public void computeScroll() {        if(mScroller.computeScrollOffset()){            scrollTo(0, mScroller.getCurrY());            invalidate();        }    }}



xml:

<?xml version="1.0" encoding="utf-8"?><com.test.git.coordinatorlayout.Behavior.ViewParent xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context=".Activity.MainActivity">    <FrameLayout        android:layout_width="match_parent"        android:layout_height="wrap_content">        <View            android:layout_width="match_parent"            android:layout_height="200dp"            android:background="@mipmap/ic_launcher"            />    </FrameLayout>    <Button        android:id="@+id/bt_click"        android:textSize="15dp"        android:text="分割线"        android:layout_width="wrap_content"        android:layout_height="50dp"        android:layout_marginTop="200dp"        android:layout_gravity="center_horizontal"        />    <android.support.v7.widget.RecyclerView        android:id="@+id/mRecyclerView"        android:layout_marginTop="250dp"        android:layout_width="match_parent"        android:layout_height="match_parent">    </android.support.v7.widget.RecyclerView></com.test.git.coordinatorlayout.Behavior.ViewParent>

相关文章:点击打开链接   点击打开链接

源码:点击打开链接


0 0
原创粉丝点击