Java tutorial
/* * Copyright (c) 2016 Ni YueMing<niyueming@163.com> * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. * */ package net.nym.napply.library.behavior; import android.content.Context; import android.support.design.widget.AppBarLayout; import android.support.design.widget.CoordinatorLayout; import android.support.v4.view.ScrollingView; import android.support.v4.view.ViewCompat; import android.support.v4.widget.NestedScrollView; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import net.nym.napply.library.utils.Log; /** * @author niyueming * @date 2016-09-08 * @time 10:12 */ public class HeadOffsetBehavior extends CoordinatorLayout.Behavior<View> { int offsetTotal = 0; boolean scrolling = false; public HeadOffsetBehavior(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) { return super.onDependentViewChanged(parent, child, dependency); } float y; @Override public boolean onTouchEvent(CoordinatorLayout parent, View child, MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: if (inRangeOfView(child, ev)) { y = ev.getY(); return true; } break; case MotionEvent.ACTION_MOVE: offset(child, (int) (y - ev.getY())); y = ev.getY(); break; } return super.onTouchEvent(parent, child, ev); } public static boolean inRangeOfView(View view, MotionEvent ev) { int[] location = new int[2]; view.getLocationOnScreen(location); int x = location[0]; int y = location[1]; if (ev.getRawX() < x || ev.getRawX() > (x + view.getWidth()) || ev.getRawY() < y || ev.getRawY() > (y + view.getHeight())) { return false; } return true; } @Override public void onNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) { // if (child instanceof NestedScrollView){ // NestedScrollView nestedScrollView = (NestedScrollView) child; // View childView = nestedScrollView.getChildAt(0); // if(childView != null && childView.getMeasuredHeight() <= nestedScrollView.getScrollY() + nestedScrollView.getHeight()) // { // Log.e("onscroll:%d,%d",dyConsumed,dyUnconsumed); offset(child, dyConsumed + dyUnconsumed); // } // } } @Override public boolean onNestedFling(CoordinatorLayout coordinatorLayout, View child, View target, float velocityX, float velocityY, boolean consumed) { return super.onNestedFling(coordinatorLayout, child, target, velocityX, velocityY, consumed); } @Override public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) { return true; } public void offset(View child, int dy) { int old = offsetTotal; int top = offsetTotal - dy; top = Math.max(top, -child.getHeight()); top = Math.min(top, 0); offsetTotal = top; if (old == offsetTotal) { scrolling = false; return; } int delta = offsetTotal - old; child.offsetTopAndBottom(delta); scrolling = true; } }