如何在ViewPager中禁用HorizontalScrollView的滚动

4

我在ViewPager中放置了一个Horizontal ScrollView。目标是仅使用软件触发的水平滚动视图。所有的滚动手势应该由ViewPager处理。

我已经通过创建自定义ViewPager来拦截所有的滑动手势来实现了这一点:

public class GreedyViewPager extends ViewPager {

    GestureDetector mGestureDetector;
    View.OnTouchListener mGestureListener;

    public GreedyViewPager(Context context) {
        super(context);
        initGestureDetector(context);
    }

    public GreedyViewPager(Context context, AttributeSet attributeSet) {
        super(context, attributeSet);
        initGestureDetector(context);
    }

    void initGestureDetector(Context context){
        mGestureDetector = new GestureDetector(context, new ScrollDetector());
        ViewConfiguration vc = ViewConfiguration.get(context);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return super.onInterceptTouchEvent(ev) || mGestureDetector.onTouchEvent(ev);
    }

    class ScrollDetector extends SimpleOnGestureListener {
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            return true;
        }

        @Override
        public boolean onDoubleTap(MotionEvent e) {
            return true;
        }
    }
}

很遗憾,它不能在所有设备上良好运行,有时我必须多次滑动才能进入ViewPager的下一个位置。

有什么办法可以让它更好吗?


https://dev59.com/AGsz5IYBdhLWcg3wj4ra - Android
请看以下两个链接:https://dev59.com/y2sz5IYBdhLWcg3wDzwA 和 https://dev59.com/TWkw5IYBdhLWcg3wyNgV。或许对您有所帮助。 - Android
@Pragna 我想做相反的事情,这个解决方案锁定了 ViewPager,我希望 ViewPager 拦截所有滚动事件。 - kmalmur
尝试使用viewPager.setDescendantFocusability(ViewPager.FOCUS_BEFORE_DESCENDANTS); - Sripathi
@kmalmur 你能解决这个问题吗?我今天也遇到了同样的问题,而 focus_before_descendants 并没有起作用。 - jennymo
4个回答

4
为了解决这个问题,我按照以下步骤操作:
首先,我创建了一个自定义的HorizontalScrollView类:
public class MyScrollView extends HorizontalScrollView{

    public MyScrollView(Context context) {
        super(context);

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

    }

    public MyScrollView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

    }

    @Override
    protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX,boolean clampedY) {    

        Log.e(" horizontal ", " - "+scrollX);
            // here i call the listener i have created
        scrollViewListener.onHorizontalScrollChanged(scrollX, scrollY);

        super.onOverScrolled(0, scrollY, true, true);       
    }

    // i create a scroll view listener, and i instantiate this from main Activity
    private ScrollViewListener scrollViewListener = null;   
    public interface ScrollViewListener {
        void onHorizontalScrollChanged(int x, int y);
    }

    public void setScrollViewListener(ScrollViewListener scrollViewListener) {
        this.scrollViewListener = scrollViewListener;
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);    
    }

}

在你的MainActivity中实现这个:
implements MyScrollView.ScrollViewListener

@Override
public void onHorizontalScrollChanged(int x, int y) {
      // In your ViewPager call this method
      mPager.scrollBy(x, y);
}

在你的MainActivity中,在onCreate方法中添加以下内容:

还有,您需要添加以下内容:

// i have also added this custom HorizontalScrollView to my XML
MyScrollView myScrollView = (MyScrollView) findViewById(R.id.h_scroll);
myScrollView.setScrollViewListener(this);

我实现了这段代码,它对我有效,希望对你也有效 :)

1

你需要创建自定义的ScrollView并覆盖onInterceptTouchEvent方法,然后从该方法中返回false。

public class StoppableScrollView extends ScrollView {

  public StoppableScrollView(Context context) {
    super(context);
  }


  @Override
  public boolean onInterceptTouchEvent(MotionEvent ev) {
    return false;
  }

}


我已经尝试过了。它可以工作,但是HorizontalScrollView内部的项目不可点击。我需要拦截滚动事件。 - kmalmur

0

这是你需要的吗?

@Override
public boolean dispatchTouchEvent(MotionEvent ev){
   if(ev.getAction()==MotionEvent.ACTION_MOVE)
      return true;
   return super.dispatchTouchEvent(ev);
}

这并不是很容易,滚动事件由Action_DOWN、Action_MOVE和Action_UP组成。有时甚至会有不同的配置,例如在第二次点击后立即滚动时。 - kmalmur

0
尝试设置ViewPager的DescendantFocusability属性。
 viewPager.setDescendantFocusability(ViewPager.FOCUS_BEFORE_DESCENDANTS);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接