【问题标题】:SwipeRefreshLayout intercepts with ViewPagerSwipeRefreshLayout 用 ViewPager 拦截
【发布时间】:2022-04-20 20:05:45
【问题描述】:

我有一个包裹在 SwipeRefreshLayout 中的 ViewPager。 有时,当我向左/向右滑动时,会触发 SRL。这主要发生在我处于片段顶部时。

我该如何解决这个问题?我是否需要收听某种事件才能在特定时间禁用 SRL? 我还没有真正找到任何关于它的东西,所以我怀疑这是谷歌的一个实际错误,而是我是否错误地实现了一些东西?对此有何想法?

这是我的布局:

<android.support.v4.widget.SwipeRefreshLayout
    android:id="@+id/mainSwipeContainer"
    android:layout_width="wrap_content"
    android:layout_height="match_parent">

    <android.support.v4.view.ViewPager
        android:id="@+id/mainViewPager"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

</android.support.v4.widget.SwipeRefreshLayout>

谢谢!如果我遗漏任何信息,请告诉我。

【问题讨论】:

  • 在 ViewPager 中设置的 Fragment 内部使用 SwipeRefreshLayout
  • @DhawalSodhaParmar 我曾经有过,但由于每次刷新都会刷新整个 ViewPager,我认为将它放在外面会更有意义!例如 - 如果我在一个选项卡上刷新然后向右滚动,应用程序仍在刷新,但指示器不会显示在新选项卡上。

标签: android android-viewpager swiperefreshlayout


【解决方案1】:

我设法解决了:

mainViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(mainTabLayout) {
    @Override
    public void onPageScrollStateChanged(int state) {
        toggleRefreshing(state == ViewPager.SCROLL_STATE_IDLE);
    }
});

您的 toggleRefreshing() 应如下所示:

public void toggleRefreshing(boolean enabled) {
    if (swipeRefreshLayout != null) {
        swipeRefreshLayout.setEnabled(enabled);
    }
}

【讨论】:

  • 好主意!我被困在这上面了。
  • 好吧,其实我用的是这个:swipeRefreshLayout.setEnabled(state != ViewPager.SCROLL_STATE_DRAGGING);但这个想法是真正得到解决方案。
  • 出色的解决方案!!
【解决方案2】:

检查页面滚动状态是一种好方法,但是当用户更改页面时,动画微调器将消失,这是糟糕的用户体验。

解决这个问题:

viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout) {
    @Override
    public void onPageScrollStateChanged(int state) {
        if (swipeRefreshLayout != null && !swipeRefreshLayout.isRefreshing()) {
            swipeRefreshLayout.setEnabled(state == ViewPager.SCROLL_STATE_IDLE);
        }
    }
});

【讨论】:

  • Crosswind 解决方案和 alexwan02 解决方案的组合就像魅力一样。非常感谢你们。我被这个困住了。
【解决方案3】:
public class CSwipeRefreshLayout extends SwipeRefreshLayout {
  private int mTouchSlop;
  private float mPrevx;
  private float mPrevy;
  public CSwipeRefreshLayout(Context context) {
    this(context, null);
  }

  public CSwipeRefreshLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
    mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
  }

  @Override
  public boolean onInterceptTouchEvent(MotionEvent ev) {
    switch (ev.getAction()) {
      case MotionEvent.ACTION_DOWN:
        mPrevx = MotionEvent.obtain(ev).getX();
        mPrevy = MotionEvent.obtain(ev).getY();
        break;
      case MotionEvent.ACTION_MOVE:
        final float evX = ev.getX();
        final float evy = ev.getY();
        float xDiff = Math.abs(evX - mPrevx);
        float yDiff = Math.abs(evy - mPrevy);
        if (xDiff > mTouchSlop && xDiff > yDiff) {
          return false;
        }
    }
    return super.onInterceptTouchEvent(ev);
  }
}

【讨论】:

    【解决方案4】:

    受@Crosswind 和@Gombal 启发:ViewPager2 的 kotlin 扩展功能解决方案

    binding.topViewPager.ignorePullToRefresh(binding.swipeRefreshLayout)
    
    fun ViewPager2.ignorePullToRefresh(swipeRefreshLayout: SwipeRefreshLayout) {
        this.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
            override fun onPageScrollStateChanged(state: Int) {
                super.onPageScrollStateChanged(state)
                if (!swipeRefreshLayout.isRefreshing) {
                    swipeRefreshLayout.isEnabled = state == SCROLL_STATE_IDLE
                }
            }
        })
    }
    

    【讨论】:

    • 问题是,每个viewpager的页面都有不同的滑动刷新布局
    猜你喜欢
    • 1970-01-01
    • 2016-02-03
    • 2015-08-05
    • 1970-01-01
    • 1970-01-01
    • 2021-05-02
    • 1970-01-01
    • 2015-09-22
    • 1970-01-01
    相关资源
    最近更新 更多