Closed KeQian closed 4 years ago
总结下 可能作者停止更新了 我遇到的问题 总结下来就是onNestedPreFling 导致的 兼容28.0.0主要有以下几步 1.跟换到28.0.0后 修改 onStopNestedScroll onNestedPreScroll onStartNestedScroll 过时方法 ,此时基本功能已经能实现 但是 下拉至图片至放大效果 快速上滑 中间布局(TAG_MIDDLE = "middle")等布局 错位 解决这个问题请看第二步
2.修改 onNestedPreFling 始终return true; 禁用快速滑动即可
例子: @Override public boolean onNestedPreFling(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, float velocityX, float velocityY) { Log.e("Behavior","onNestedPreFling"); if (velocityY > 100) {//当y速度>100,就秒弹回 isAnimate = false; } return true; }
兄弟,AndroidX按照这个处理也不能下拉放大
onStartNestedScroll 方法也需要强制返回true
我的就是迁移了AndroidX的啊 提示下 修改 onStopNestedScroll onNestedPreScroll onStartNestedScroll 过时方法 ,还不行的话 看看imageview tag对不对
onStartNestedScroll 方法也需要强制返回true
这是我的
/**
@return 返回true表示接受滚动 */ @Override public boolean onStartNestedScroll(CoordinatorLayout parent, AppBarLayout child, View directTargetChild, View target, int nestedScrollAxes, int type) { Log.e("Behavior","onStartNestedScroll" + type + "//" + nestedScrollAxes); isNestedPreFlingEnable=false; isXia=false; issahng=false;
isAnimate = true;
if (target instanceof DisInterceptNestedScrollView) return true; //这个布局就是middleLayout
return super.onStartNestedScroll(parent, child, directTargetChild, target, nestedScrollAxes, type);
}
/**
toolbar背景变色 */ public class AppBarLayoutOverScrollViewBehavior extends AppBarLayout.Behavior {
private static final String TAG_TOOLBAR = "toolbar"; private static final String TAG_MIDDLE = "middle"; private static final float TARGET_HEIGHT = 1600; private View mTargetView; private int mParentHeight; private int mTargetViewHeight; private float mTotalDy; private float mLastScale; private int mLastBottom; private boolean isAnimate; private Toolbar mToolBar; private ViewGroup middleLayout;//个人信息布局 private int mMiddleHeight; private boolean isRecovering = false;//是否正在自动回弹中
private final float MAX_REFRESH_LIMIT = 0.3f;//达到这个下拉临界值就开始刷新动画
public AppBarLayoutOverScrollViewBehavior() { }
public AppBarLayoutOverScrollViewBehavior(Context context, AttributeSet attrs) { super(context, attrs); }
/**
@return 返回true表示子View重新布局,返回false表示请求默认布局 */ @Override public boolean onLayoutChild(CoordinatorLayout parent, AppBarLayout abl, int layoutDirection) { boolean handled = super.onLayoutChild(parent, abl, layoutDirection);
if (mToolBar == null) { mToolBar = (Toolbar) parent.findViewWithTag(TAG_TOOLBAR); } if (middleLayout == null) { middleLayout = (ViewGroup) parent.findViewWithTag(TAG_MIDDLE); } // 需要在调用过super.onLayoutChild()方法之后获取 if (mTargetView == null) { mTargetView = parent.findViewById(R.id.uc_zoomiv); if (mTargetView != null) { initial(abl); } } abl.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() { @Override public final void onOffsetChanged(AppBarLayout appBarLayout, int i) { mToolBar.setAlpha(Float.valueOf(Math.abs(i)) / Float.valueOf(appBarLayout.getTotalScrollRange())); } }); return handled; }
/**
@return 返回true表示接受滚动 */ @Override public boolean onStartNestedScroll(CoordinatorLayout parent, AppBarLayout child, View directTargetChild, View target, int nestedScrollAxes, int type) { Log.e("Behavior","onStartNestedScroll" + type + "//" + nestedScrollAxes); isNestedPreFlingEnable=false; isXia=false; issahng=false;
isAnimate = true; if (target instanceof DisInterceptNestedScrollView) return true; //这个布局就是middleLayout return super.onStartNestedScroll(parent, child, directTargetChild, target, nestedScrollAxes, type); }
/**
private Boolean isNestedPreFlingEnable=false; private Boolean isXia=false; private Boolean issahng=false;
@Override public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int dx, int dy, int[] consumed, int type) {
if (dy<0){isXia=true;}
if (dy>0){issahng=true;}
if (isXia && issahng){isNestedPreFlingEnable=true;}
Log.e("Behavior","onNestedPreScroll==" + consumed[1]+"//"+dy);
if (!isRecovering) {
if (mTargetView != null && ((dy < 0 && child.getBottom() >= mParentHeight) || (dy > 0 && child.getBottom() > mParentHeight))) {
scale(child, target, dy);
return;
}
}
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type);
}
/**
@return 如果Behavior消耗了快速滚动返回true */ @Override public boolean onNestedPreFling(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, float velocityX, float velocityY) { Log.e("Behavior","onNestedPreFling"); if (velocityY > 100) {//当y速度>100,就秒弹回 isAnimate = false;
if (isNestedPreFlingEnable){
isNestedPreFlingEnable=false;
isXia=false;
issahng=false;
return true;
}
} return super.onNestedPreFling( coordinatorLayout, child, target, velocityX, velocityY); }
/**
@param target 发起嵌套滚动的目标View(即AppBarLayout下面的ScrollView或RecyclerView) */ @Override public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, AppBarLayout abl, View target, int type) { isNestedPreFlingEnable=false; isXia=false; issahng=false;
Log.e("Behavior","onStopNestedScroll"); recovery(abl); super.onStopNestedScroll(coordinatorLayout, abl, target, type); }
private void initial(AppBarLayout abl) { abl.setClipChildren(false); mParentHeight = abl.getHeight(); mTargetViewHeight = mTargetView.getHeight(); mMiddleHeight = middleLayout.getHeight(); }
private void scale(AppBarLayout abl, View target, int dy) { Log.e("Behavior","scale"); mTotalDy += -dy; mTotalDy = Math.min(mTotalDy, TARGET_HEIGHT); mLastScale = Math.max(1f, 1f + mTotalDy / TARGET_HEIGHT); ViewCompat.setScaleX(mTargetView, mLastScale); ViewCompat.setScaleY(mTargetView, mLastScale); mLastBottom = mParentHeight + (int) (mTargetViewHeight / 2 * (mLastScale - 1)); abl.setBottom(mLastBottom); target.setScrollY(0);
middleLayout.setTop(mLastBottom - mMiddleHeight);
middleLayout.setBottom(mLastBottom);
if (onProgressChangeListener != null) {
float progress = Math.min((mLastScale - 1) / MAX_REFRESH_LIMIT, 1);//计算0~1的进度
onProgressChangeListener.onProgressChange(progress, false);
}
}
public interface onProgressChangeListener { /**
public void setOnProgressChangeListener(AppBarLayoutOverScrollViewBehavior.onProgressChangeListener onProgressChangeListener) { this.onProgressChangeListener = onProgressChangeListener; }
onProgressChangeListener onProgressChangeListener;
private void recovery(final AppBarLayout abl) { if (isRecovering) { return; } if (mTotalDy > 0) { isRecovering = true; mTotalDy = 0; if (isAnimate) { ValueAnimator anim = ValueAnimator.ofFloat(mLastScale, 1f).setDuration(200); anim.addUpdateListener( new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) {
float value = (float) animation.getAnimatedValue();
ViewCompat.setScaleX(mTargetView, value);
ViewCompat.setScaleY(mTargetView, value);
abl.setBottom((int) (mLastBottom - (mLastBottom - mParentHeight) * animation.getAnimatedFraction()));
middleLayout.setTop((int) (mLastBottom -
(mLastBottom - mParentHeight) * animation.getAnimatedFraction() - mMiddleHeight));
if (onProgressChangeListener != null) {
float progress = Math.min((value - 1) / MAX_REFRESH_LIMIT, 1);//计算0~1的进度
onProgressChangeListener.onProgressChange(progress, true);
}
}
}
);
anim.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
Log.e("Behavior","onAnimationStart");
isRecovering = true;
}
@Override
public void onAnimationEnd(Animator animation) {
Log.e("Behavior","onAnimationEnd");
isRecovering = false;
}
@Override
public void onAnimationCancel(Animator animation) {
Log.e("Behavior","onAnimationCancel");
}
@Override
public void onAnimationRepeat(Animator animation) {
Log.e("Behavior","onAnimationRepeat");
}
});
anim.start();
} else {
ViewCompat.setScaleX(mTargetView, 1f);
ViewCompat.setScaleY(mTargetView, 1f);
abl.setBottom(mParentHeight);
middleLayout.setTop(mParentHeight - mMiddleHeight);
middleLayout.setBottom(mParentHeight);
isRecovering = false;
if (onProgressChangeListener != null) {
onProgressChangeListener.onProgressChange(0, true);
}
}
}
}
}
非常感谢,我现在试下
你那边上滑的时候会有抖动吗? 我这会
这是ViewGroup嵌套导致的吧
不要嵌套 NestedScrollView
ViewPage 或者RecycleView直接使用
像这样 <androidx.recyclerview.widget.RecyclerView android:id="@+id/rcvList" app:layout_behavior="@string/appbar_scrolling_view_behavior" android:layout_width="match_parent" android:layout_height="match_parent" />
额,我是直接在这个demo上跑的,你那边慢慢往上滑再放开会不会?
嘿嘿 我的如丝般顺滑
问题在于onStartNestedScroll onNestedPreScroll onStopNestedScroll 在28+过时了,更新了本地API后,效果恢复正常,代码已更新,下面是官方通知
onStartNestedScroll ()onStartNestedScroll()等 方法过时 导致下拉无效,更改最新方法后,下拉至图片至放大效果 快速上滑 中间布局(TAG_MIDDLE = "middle")等布局 错位