gpt4 book ai didi

android - PagerSnapHelper 中的 From-To Page Changed 监听器

转载 作者:行者123 更新时间:2023-11-29 15:35:12 26 4
gpt4 key购买 nike

我在水平 RecyclerView 中使用 PagerSnapHelper 来实现类似 View 寻呼机的行为。

final PagerSnapHelper pagerSnapHelper = new PagerSnapHelper();
pagerSnapHelper.attachToRecyclerView(recyclerView);

效果很好,但我希望能够在用户向任一方向更改页面时获得回调。所以类似于 onSwipeLeft/onSwipeRight 回调。

我尝试在 PagerSnapHelper 中使用 findTargetSnapPosition,但这只给我 targetIndex 而不是当前索引。我尝试过类似的方法,但它并不总是有效。

@Override
public int findTargetSnapPosition(RecyclerView.LayoutManager layoutManager, int velocityX, int velocityY) {
final int targetPos = super.findTargetSnapPosition(layoutManager, velocityX, velocityY);

final View currentView = findSnapView(layoutManager);
final int currentPos = layoutManager.getPosition(currentView);

if (currentPos < targetPos) {
callback.onSwipeRight();
} else if (currentPos > targetPos) {
callback.onSwipeLeft();
}

return targetPos;
}

有没有更好的方法来实现这个总是有效的?谢谢!

最佳答案

更新 2
!!重要提示!!
如果您以编程方式调用 scrollTo() 并将 SnapPagerScrollListenerON_SETTLED 一起使用,则不会调用 onScrollStateChanged。所以旧的捕捉位置不会得到更新。 WIP,我会在修复后立即更新类(class)。

更新

原始类在第一个布局上通知时存在一些问题。现在它仅在项目位置第一次从 RecyclerView.NO_POSITION 更改为其他内容时触发。

为了进一步扩展为仅在用户手势时忽略/触发,因此对 scrollTo() 的非编程调用,请注意 onScrolled() 会被 dx 触发== 0 和 dy == 0 在编程调用的情况下。

public class SnapPagerScrollListener extends RecyclerView.OnScrollListener {

// Constants
public static final int ON_SCROLL = 0;
public static final int ON_SETTLED = 1;

@IntDef({ON_SCROLL, ON_SETTLED})
public @interface Type {
}

public interface OnChangeListener {
void onSnapped(int position);
}

// Properties
private final PagerSnapHelper snapHelper;
private final int type;
private final boolean notifyOnInit;
private final OnChangeListener listener;
private int snapPosition;

// Constructor
public SnapPagerScrollListener(PagerSnapHelper snapHelper, @Type int type, boolean notifyOnInit, OnChangeListener listener) {
this.snapHelper = snapHelper;
this.type = type;
this.notifyOnInit = notifyOnInit;
this.listener = listener;
this.snapPosition = RecyclerView.NO_POSITION;
}

// Methods
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if ((type == ON_SCROLL) || !hasItemPosition()) {
notifyListenerIfNeeded(getSnapPosition(recyclerView));
}
}

@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (type == ON_SETTLED && newState == RecyclerView.SCROLL_STATE_IDLE) {
notifyListenerIfNeeded(getSnapPosition(recyclerView));
}
}

private int getSnapPosition(RecyclerView recyclerView) {
RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
if (layoutManager == null) {
return RecyclerView.NO_POSITION;
}

View snapView = snapHelper.findSnapView(layoutManager);
if (snapView == null) {
return RecyclerView.NO_POSITION;
}

return layoutManager.getPosition(snapView);
}

private void notifyListenerIfNeeded(int newSnapPosition) {
if (snapPosition != newSnapPosition) {
if (notifyOnInit && !hasItemPosition()) {
listener.onSnapped(newSnapPosition);
} else if (hasItemPosition()) {
listener.onSnapped(newSnapPosition);
}

snapPosition = newSnapPosition;
}
}

private boolean hasItemPosition() {
return snapPosition != RecyclerView.NO_POSITION;
}
}


用法:
只需将 SnapPagerScrollListener 实例添加到您的 RecyclerView

your_recycler_view.addOnScrollListener(new SnapPagerScrollListener(your_snap_helper, SnapPagerScrollListener.ON_SCROLL/ON_SETTLED, true/false, your_on_changed_listener));


Type 属性用于定义何时触发回调。

  1. ON_SCROLL:用于在新 View /页面通过中间时立即通知回调
  2. ON_SETTLED:用于通知RecyclerViews状态为SCROLL_STATE_IDLE后的回调。我使用该模式仅在滚动稳定后触发 API 调用。

关于android - PagerSnapHelper 中的 From-To Page Changed 监听器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52083768/

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