SwipeRefreshLayout 拦截与 ViewPager
SwipeRefreshLayout intercepts with ViewPager
我有一个 ViewPager 包裹在 SwipeRefreshLayout 中。
有时,当我滑动到 left/right 时,SRL 会被触发。这主要发生在我位于片段顶部时。
我该如何解决这个问题?我是否需要监听某种事件才能在特定时间内禁用 SRL?
我还没有真正找到任何关于它的信息,所以我怀疑这是 Google 的一个实际错误,而是我是否错误地实施了某些事情?对此有什么想法吗?
这是我的布局:
<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>
谢谢!如果我遗漏了任何信息,请告诉我。
我设法解决了:
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);
}
}
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);
}
}
检查页面滚动状态是一个好方法,但是当用户更改页面时,动画微调器将消失,这是糟糕的用户体验。
解决这个问题:
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和@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 包裹在 SwipeRefreshLayout 中。 有时,当我滑动到 left/right 时,SRL 会被触发。这主要发生在我位于片段顶部时。
我该如何解决这个问题?我是否需要监听某种事件才能在特定时间内禁用 SRL? 我还没有真正找到任何关于它的信息,所以我怀疑这是 Google 的一个实际错误,而是我是否错误地实施了某些事情?对此有什么想法吗?
这是我的布局:
<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>
谢谢!如果我遗漏了任何信息,请告诉我。
我设法解决了:
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);
}
}
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);
}
}
检查页面滚动状态是一个好方法,但是当用户更改页面时,动画微调器将消失,这是糟糕的用户体验。
解决这个问题:
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和@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
}
}
})
}