【问题标题】:how to disable viewpager adapter on touching specific views?如何在触摸特定视图时禁用 viewpager 适配器?
【发布时间】:2013-05-02 16:01:27
【问题描述】:

我有一个 viewpager,它在向左/向右滑动时在选项卡之间切换。在我的第二个选项卡中,我有一些自定义视图,它们具有用于捏合和拖动的侦听器,但是当我尝试捏合或拖动时,viewpager 开始滑动页面.

我想到的一个解决方案是在触摸这些特定视图时禁用滑动,并且仅在触摸这些视图之外时才滑动。这可能吗?

更新: @Asok 好心地提供了解决方案。但随后更新了在我的情况下不起作用的代码,所以我发布了上一段对我有用的代码:

public class CustomViewPager extends ViewPager {
private boolean swipeable = true;

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

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

// Call this method in your motion events when you want to disable or enable
// It should work as desired.
public void setSwipeable(boolean swipeable) {
    this.swipeable = swipeable;
}

@Override
public boolean onInterceptTouchEvent(MotionEvent arg0) {
    return (this.swipeable) ? super.onInterceptTouchEvent(arg0) : false;
}

假设我有一个可拖动的视图,我需要在拖动开始时禁用滑动,并在拖动完成时重新启用,所以在我所谓的视图的 TouchEvent 中:

    @Override
public boolean onTouchEvent(MotionEvent event) {
    switch(event.getAction()) {
    case MotionEvent.ACTION_DOWN:
//disable swiping when the button is touched
((ActivityOriginal) getActivity()).setSwipeable(false);
//the rest of the code...
        break;
    case MotionEvent.ACTION_MOVE:

        break;
    case MotionEvent.ACTION_UP:
//re enable swipping when the touch is stopped
//the rest of the code...
((ActivityOriginal) getActivity()).setSwipeable(true);
        break;
    }
    return true;
}

【问题讨论】:

    标签: android android-viewpager


    【解决方案1】:

    我首先想到的是有一个自定义的ViewPager,当您的触摸侦听器收到特定事件的通知时,您可以将ViewPager 中的boolean 设置为false 和以最适合您的应用程序的方式将其设置回 true。

    public class CustomViewPager extends ViewPager {
        private boolean swipeable = true;
    
        public CustomViewPager(Context context) {
            super(context);
        }
    
        public CustomViewPager(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        // Call this method in your motion events when you want to disable or enable
        // It should work as desired.
        public void setSwipeable(boolean swipeable) {
            this.swipeable = swipeable;
        }
    
        @Override
        public boolean onInterceptTouchEvent(MotionEvent arg0) {
            return (this.swipeable) ? super.onInterceptTouchEvent(arg0) : false; 
        }
    
    }
    

    确保将布局文件更改为显示:

    <com.your.package.CustomViewPager .. />
    

    代替:

    <android.support.v4.view.ViewPager .. />
    

    编辑 2

    这是我的设置(使用上述CustomViewPager):

    CustomViewPager mViewPager;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        // Set up the action bar.
        final ActionBar actionBar = getActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
    
        // Create the adapter that will return a fragment for each of the three
        // primary sections of the app.
        mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
    
        // Set up the CustomViewPager with the sections adapter.
        mViewPager = (CustomViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(mSectionsPagerAdapter);
        mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                actionBar.setSelectedNavigationItem(position);
            }
        });
    
        // For each of the sections in the app, add a tab to the action bar.
        for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
            actionBar.addTab(actionBar.newTab()
                    .setText(mSectionsPagerAdapter.getPageTitle(i))
                    .setTabListener(this));
        }
    
    }
    
    public void swipeOn(View v) {
        mViewPager.setSwipeable(true);
    }
    
    public void swipeOff(View v) {
        mViewPager.setSwipeable(false);
    }
    

    上面显示的onCreate 在我的MainActivity 类中,它扩展了FragmentActivity 并实现了ActionBar.TabListener

    【讨论】:

    • @asok 如何从不同的片段访问 customviewpager 实例(在活动中创建)?
    • @Asok 不幸的是,在使用 customviewpager 而不是 viewpager 之后,没有任何 UI 元素对触摸、甚至按钮和列表视图做出反应。
    • @afterburner 很抱歉,我测试了 onInterceptTouchEvent 而不是 onTouchEvent,它通过禁用滑动而不是其他触摸事件来为我工作。
    • @androiddeveloper 在我纠正自己之后,它正在工作并且能够打开和关闭。
    • @Asok onInterceptTouchEvent 为我解决了问题,但是 onTouchEvent(当交换设置为 false 时,选项卡仍然是可交换的,但每次交换的交换速度很慢,例如 1 毫米)。所以我使用了 onInterceptTouchEvent。谢谢帮忙。只是希望我能给你更多的积分来解决这个问题。
    【解决方案2】:

    我正在使用requestDisallowInterceptTouchEvent(true) int 也有拖动事件的视图的 onTouchEvent 侦听器。

    @Override
    public boolean onTouchEvent(MotionEvent event) {
    
        ViewParent parent = getParent(); 
        // or get a reference to the ViewPager and cast it to ViewParent
    
        parent.requestDisallowInterceptTouchEvent(true);
    
        // let this view deal with the event or
        return super.onTouchEvent(event);
    }
    

    【讨论】:

    • 你救了我的命。谢谢:)
    • 正是我想要的!谢谢!
    【解决方案3】:

    我是这样用的

    public void setSwipeable(boolean swipeable)
    {
        this.swipeable = swipeable;
    }
    
    @Override
    public void scrollTo(int x, int y){
        if (swipeable){
            super.scrollTo(x, y);
        }
    }
    

    【讨论】:

      【解决方案4】:

      如果您知道不想在视图寻呼机中拦截触摸事件的位置,您可以像我一样做一些事情。

       @Override
       public boolean onInterceptTouchEvent(MotionEvent arg0) {
          if(arg0.getY()>getHeight()/2)return false;
          return super.onInterceptTouchEvent(arg0);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-02-10
        • 1970-01-01
        • 1970-01-01
        • 2017-04-15
        • 1970-01-01
        • 1970-01-01
        • 2015-05-04
        相关资源
        最近更新 更多