提问者:小点点

重叠片段和触摸事件


我有一个ViewPager和一个自定义的PagerAdapter,它显示一组片段。

这些片段(故意)彼此重叠,以便我可以使用PageTransformer,使其看起来好像用户正在从堆栈(几乎像一副牌)中滑动片段。

问题是每个片段都有自己的视图/Widget(例如,Seekbar),由于重叠,它们占据相同的坐标,有时触摸事件会被当前片段下面的片段捕获(例如,用户调整Seekbar的位置,但不是更新当前显示的Seekbar,而是更新下一个片段中的Seekbar的进度)。

我遇到过这个答案,但它不是完全相同的问题。有人发现过类似的问题吗?处理这个问题的最聪明的方法是什么(除了懒惰的解决方案:将PageTransformer更改为不重叠片段的方法)?

编辑:

在我的片段类中,我有:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)        
{
    View rootView = inflater.inflate(R.layout.fragment, container, false);

    rootView.setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            return true;
        }
    });
}

正如Zsimbor Erdödy-Nagy所建议的,但这并没有帮助:当前片段下面的小部件仍然有可能接收事件而不是当前片段的事件。

我也研究过这个悬而未决的问题,但没有成功。


共3个答案

匿名用户

如果您仍在寻找解决方案,那么您应该看看这个:

问题58918。

在这里您可以找到问题的答案。引用链接:

如果我没记错的话,是在4.1之后,框架将自定义子绘图顺序视为分发触摸事件的隐含Z排序。如果您的视图在此页面转换后重叠,它们可能不会按照旧平台版本的预期顺序接收触摸事件。检查哪个视图正在接收触摸事件以确定。

如果这是你看到的,你有几个选择:

  • 在PagerAdapter中添加/删除子视图时强制执行所需的顺序
  • 当页面不再完全可见时,删除PageTransformer应用的X翻译-即“位置”参数报告完整的-1或1。

示例:

this.viewPager.setPageTransformer(true, new PageTransformer() {

        @Override
        public void transformPage(View page, float position) {
            float translationX;
            float scale;
            float alpha;

            if (position >= 1 || position <= -1) {
                // Fix for https://code.google.com/p/android/issues/detail?id=58918
                translationX = 0;
                scale = 1;
                alpha = 1;
            } else if (position >= 0) {
                translationX = -page.getWidth() * position;
                scale = -0.2f * position + 1;
                alpha = Math.max(1 - position, 0);
            } else {
                translationX = 0.5f * page.getWidth() * position;
                scale = 1.0f;
                alpha = Math.max(0.1f * position + 1, 0);
            }

            ViewHelper.setTranslationX(page, translationX);
            ViewHelper.setScaleX(page, scale);
            ViewHelper.setScaleY(page, scale);
            ViewHelper.setAlpha(page, alpha);
        }
});

匿名用户

在这种情况下,您的所有片段都必须有一个背景视图,以阻止TochEvents传播到后面的片段。

我猜你已经有了这些片段的不透明背景,否则后面的片段会通过当前位于堆栈顶部的片段显示出来。所以尝试为所有片段的根ViewGroup实例设置一个ClickListener,它什么都不做,它只是捕获触摸事件。

匿名用户

如果有人遇到这个问题(这不仅可能发生在ViewPager上),只需将此属性添加到层次结构顶部的布局中:

android:clickable="true"

通过这种方式,它将处理点击,不会对它们做任何事情,但至少避免它们到达后台的片段。