gpt4 book ai didi

android - 自定义 CoordinatorLayout.Behavior 和 RecyclerView 滚动问题

转载 作者:太空宇宙 更新时间:2023-11-03 13:13:55 26 4
gpt4 key购买 nike

我有一个 CoordinatorLayout,它有两个 child ,一个用作标题的 View 和一个 RecyclerView:

<android.support.design.widget.CoordinatorLayout
android:id="@+id/coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent">

<LinearLayout
android:id="@+id/view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_horizontal"
app:layout_behavior="some.package.AlphaBehavior">

<ImageView
android:id="@+id/header_iv"
style="@style/some_style"/>

<TextView
android:id="@+id/header_retails_tv"
style="@style/some_style_tv"
android:text="@string/some_text"/>

</LinearLayout>

<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false" />

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

我将填充动态设置为 RecyclerView 并设置为 clipToPaddingfalse,所以 RecyclerView 显示在标题下方,当用户向上滚动时,RecyclerView 显示在标题 View 上方。

我制作了一个自定义的 CoordinatorLayout.Behavior,以便在用户向上滚动 list 时淡出 View ,并在必须滚动标题时淡入再次可见,AlphaBehavior:

public class AlphaBehavior extends CoordinatorLayout.Behavior {

private float alpha = 1.0f;
private float scrolly = 0.f;
private int headerSize = 0;

private Animation defaultFadeInAnimation;

public AlphaBehavior(Context context, AttributeSet attrs) {
super(context, attrs);


defaultFadeInAnimation = AnimationUtils.loadAnimation(context, android.R.anim.fade_in);
}

public void setHeaderSize(int headerSize) {
this.headerSize = headerSize;
}

@Override
public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
return dependency instanceof RecyclerView;
}


@Override
public void onNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {

scrolly += dyConsumed;

Log.d(Constants.TAG, dyConsumed + "/" + dyUnconsumed + "/" + scrolly);

float totalScrollY = ((RecyclerView)target).computeVerticalScrollOffset();

Log.d(Constants.TAG, "totalScrollY:" + totalScrollY);

alpha = (headerSize - totalScrollY) / headerSize;

if (alpha < 0.f) alpha = 0.f;
if (alpha > 1.0f) alpha = 1.f;

if (dyConsumed < 0 && totalScrollY > headerSize) {
alpha = 0.f;
}

Log.d(Constants.TAG, "alpha:" + alpha);

child.setAlpha(alpha);
}

@Override
public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target) {

int pos = ((LinearLayoutManager)((RecyclerView)target).getLayoutManager()).findFirstCompletelyVisibleItemPosition();

Log.d(Constants.TAG, "pos:" + pos);

if (pos == 0 && child.getAlpha() == 0.f) {
child.startAnimation(defaultFadeInAnimation);
}
}



// overriding this in case we don't the other events are not called
@Override
public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) {
return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL;
}
}

但我面临一个问题:如果用户滚动得非常快,则行为事件不会正确调用。 scrollY 成员与总滚动没有很好的关系,并且 totalScrollY 成员(通过计算 RecyclerView 的滚动获得)不正确。即使我试图在 onStopNestedScroll 事件中找到 firstCompletelyVisibleItem,但是当 recyclerView 开始时它返回位置 2 或 3列表。

最佳答案

最后,我使用 OnScrollListener 而不是使用 CoordinatorLayout.Behavior 解决了这个问题,而且效果非常好。我放了代码,也许对某人有用:

隐藏 View 的自定义 onScrollListener:

public class HideViewOnScrollListener extends RecyclerView.OnScrollListener {

private float alpha = 1.f;
private float scrolly = 0.f;

private int heightViewToHide;
private final View viewToHide;

public HideViewOnScrollListener(View viewToHide) {
this.viewToHide = viewToHide;

heightViewToHide = viewToHide.getHeight();
if (heightViewToHide == 0) {

ViewTreeObserver viewTreeObserver = viewToHide.getViewTreeObserver();
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {

heightViewToHide = viewToHide.getHeight();

if (heightViewToHide > 0)
viewToHide.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
}

}

@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);

scrolly += dy;

alpha = (heightViewToHide - scrolly) / heightViewToHide;

if (alpha < 0.f) alpha = 0.f;
if (alpha > 1.0f) alpha = 1.f;

if (dy < 0 && scrolly > heightViewToHide) {
alpha = 0.f;
}

viewToHide.setAlpha(alpha);
}
}

并且您可以通过这种方式添加到 RecyclerView:

recyclerView.addOnScrollListener(new HideViewOnScrollListener(viewToHide));

关于android - 自定义 CoordinatorLayout.Behavior 和 RecyclerView 滚动问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39724151/

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