gpt4 book ai didi

android - 当 AppBarLayout 滚动时,RecyclerView fling 会导致延迟

转载 作者:行者123 更新时间:2023-11-29 23:02:08 34 4
gpt4 key购买 nike

我有如下布局

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">


<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior=".AppBarFlingBehavior">

<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="300dp"
app:layout_scrollFlags="scroll|enterAlwaysCollapsed">


<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_collapseMode="parallax"
android:background="#ff99"/>


</android.support.design.widget.CollapsingToolbarLayout>


<TextView
android:layout_width="match_parent"
android:layout_height="200dp"
app:layout_scrollFlags="scroll|enterAlwaysCollapsed"
android:text="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"/>


</android.support.design.widget.AppBarLayout>


<android.support.v7.widget.RecyclerView
android:id="@+id/rv_sample"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="android.support.design.widget.AppBarLayout$ScrollingViewBehavior"/>


</android.support.design.widget.CoordinatorLayout>

我的问题是当我向下滑动我的AppBarLayout时,内容正在向下滚动,突然,我向上滑动我的RecyclerView,整个布局有点滞后然后按照 RecyclerView (UP) 的滑动方向向上滚动,如您在此 video 中所见.我已经尝试了很多来自许多来源的解决方案(自定义行为),但到目前为止还没有成功。有什么方法可以解决我的问题,我被困在这个问题上了一个星期。非常感谢您花时间解决我的问题。欣赏它。

最佳答案

我找到了解决方案(归功于 yangchong:https://developpaper.com/coordinator-layout-sliding-jitter-problem/ ):

应用栏行为:

/**
* <pre>
* @author yangchong
* blog : https://github.com/yangchong211
* time : 2019/03/13
* desc: Custom Behavior
* Revision: Solving Some Problems of AppbarLayout
* 1) Fast sliding appbarLayout will rebound
* 2) Fast sliding appbarLayout to fold state, immediately sliding down, there will be the problem of jitter.
* 3) Slide appbarLayout, unable to stop sliding by pressing it with your finger
*/
public class AppBarLayoutBehavior extends AppBarLayout.Behavior {

private static final String TAG = "AppbarLayoutBehavior";
private static final int TYPE_FLING = 1;
private boolean isFlinging;
private boolean shouldBlockNestedScroll;

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

@Override
public boolean onInterceptTouchEvent(CoordinatorLayout parent, AppBarLayout child, MotionEvent ev) {
LogUtil.d(TAG, "onInterceptTouchEvent:" + child.getTotalScrollRange());
shouldBlockNestedScroll = isFlinging;
switch (ev.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
// Stop fling when your finger touches the screen
stopAppbarLayoutFling(child);
break;
default:
break;
}
return super.onInterceptTouchEvent(parent, child, ev);
}

/**
* Reflect to get private flingRunnable attributes, considering the problem of variable name modification after support 28
* @return Field
* @throws NoSuchFieldException
*/
private Field getFlingRunnableField() throws NoSuchFieldException {
Class<?> superclass = this.getClass().getSuperclass();
try {
// Support design 27 and the following version
Class<?> headerBehaviorType = null;
if (superclass != null) {
headerBehaviorType = superclass.getSuperclass();
}
if (headerBehaviorType != null) {
return headerBehaviorType.getDeclaredField("mFlingRunnable");
}else {
return null;
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
// Possibly 28 or more versions
Class<?> headerBehaviorType = superclass.getSuperclass().getSuperclass();
if (headerBehaviorType != null) {
return headerBehaviorType.getDeclaredField("flingRunnable");
} else {
return null;
}
}
}

/**
* Reflect to get private scroller attributes, considering the problem of variable name modification after support 28
* @return Field
* @throws NoSuchFieldException
*/
private Field getScrollerField() throws NoSuchFieldException {
Class<?> superclass = this.getClass().getSuperclass();
try {
// Support design 27 and the following version
Class<?> headerBehaviorType = null;
if (superclass != null) {
headerBehaviorType = superclass.getSuperclass();
}
if (headerBehaviorType != null) {
return headerBehaviorType.getDeclaredField("mScroller");
}else {
return null;
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
// Possibly 28 or more versions
Class<?> headerBehaviorType = superclass.getSuperclass().getSuperclass();
if (headerBehaviorType != null) {
return headerBehaviorType.getDeclaredField("scroller");
}else {
return null;
}
}
}

/**
* Stop appbarLayout's fling event
* @param appBarLayout
*/
private void stopAppbarLayoutFling(AppBarLayout appBarLayout) {
// Get the flingRunnable variable in HeaderBehavior by reflection
try {
Field flingRunnableField = getFlingRunnableField();
Field scrollerField = getScrollerField();
if (flingRunnableField != null) {
flingRunnableField.setAccessible(true);
}
if (scrollerField != null) {
scrollerField.setAccessible(true);
}
Runnable flingRunnable = null;
if (flingRunnableField != null) {
flingRunnable = (Runnable) flingRunnableField.get(this);
}
OverScroller overScroller = (OverScroller) scrollerField.get(this);
if (flingRunnable != null) {
LogUtil.d (TAG,'Flying Runnable');
appBarLayout.removeCallbacks(flingRunnable);
flingRunnableField.set(this, null);
}
if (overScroller != null && !overScroller.isFinished()) {
overScroller.abortAnimation();
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}

@Override
public boolean onStartNestedScroll(CoordinatorLayout parent, AppBarLayout child,
View directTargetChild, View target,
int nestedScrollAxes, int type) {
LogUtil.d(TAG, "onStartNestedScroll");
stopAppbarLayoutFling(child);
return super.onStartNestedScroll(parent, child, directTargetChild, target,
nestedScrollAxes, type);
}

@Override
public void onNestedPreScroll(CoordinatorLayout coordinatorLayout,
AppBarLayout child, View target,
int dx, int dy, int[] consumed, int type) {
LogUtil.d(TAG, "onNestedPreScroll:" + child.getTotalScrollRange()
+ " ,dx:" + dx + " ,dy:" + dy + " ,type:" + type);
// When type returns to 1, it indicates that the current target is in a non-touch sliding.
// The bug is caused by the sliding of the NestedScrolling Child2 interface in Coordinator Layout when the AppBar is sliding
// The subclass has not ended its own fling
// So here we listen for non-touch sliding of subclasses, and then block the sliding event to AppBarLayout
if (type == TYPE_FLING) {
isFlinging = true;
}
if (!shouldBlockNestedScroll) {
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type);
}
}

@Override
public void onNestedScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child,
View target, int dxConsumed, int dyConsumed, int
dxUnconsumed, int dyUnconsumed, int type) {
LogUtil.d(TAG, "onNestedScroll: target:" + target.getClass() + " ,"
+ child.getTotalScrollRange() + " ,dxConsumed:"
+ dxConsumed + " ,dyConsumed:" + dyConsumed + " " + ",type:" + type);
if (!shouldBlockNestedScroll) {
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed,
dyConsumed, dxUnconsumed, dyUnconsumed, type);
}
}

@Override
public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, AppBarLayout abl,
View target, int type) {
LogUtil.d(TAG, "onStopNestedScroll");
super.onStopNestedScroll(coordinatorLayout, abl, target, type);
isFlinging = false;
shouldBlockNestedScroll = false;
}

private static class LogUtil{
static void d(String tag, String string){
Log.d(tag,string);
}
}

}

关于android - 当 AppBarLayout 滚动时,RecyclerView fling 会导致延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56849221/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com