我有ViewPager
个自定义PagerAdapter
,显示一组片段。
这些片段(故意)位于彼此之上,以便我可以使用PageTransformer,使其看起来好像用户正在从堆栈中滑动片段(几乎像一副牌)。
问题是每个片段都有自己的Views
/ Widgets
(例如搜索栏),由于重叠,它们占据相同的坐标,有时触摸事件被片段捕获如下所示(例如,用户调整搜索栏的位置,但不是更新当前显示的搜索栏,而是下一个片段中的搜索栏,它会更新其进度)。
我遇到了this answer,但这不是同一个问题。 有没有人发现类似的问题?处理这个问题的最聪明的方法是什么(除了懒惰的解决方案:将PageTransformer更改为与片段不重叠的解决方案)?
修改
在我的Fragment课程中,我有:
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;
}
});
}
正如ZsomborErdődy-Nagy所建议的那样,但是这没有帮助:当前片段仍然可以接收当前片段而不是当前片段。
我也看了this open issue,没有成功。
答案 0 :(得分:3)
如果您仍在寻找解决方案,那么您应该看一下:
在这里,您可以找到问题的答案。引用链接:
如果我没记错的话,那就是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);
}
});
答案 1 :(得分:0)
在这种情况下,所有片段都必须具有背景视图,以阻止TochEvents传播到后面的片段。
我猜你已经拥有这些片段的不透明背景,否则后面的片段会显示当前位于堆栈顶部的片段。因此,尝试为所有片段的根ViewGroup实例设置ClickListener,它只执行触摸事件。
答案 2 :(得分:0)
如果有人遇到此问题(不仅可能发生在ViewPager中),只需将此属性添加到层次结构顶部的布局中即可:
android:clickable="true"
通过这种方式,它可以处理点击,而不是对它们做任何事情,但至少避免它们在后台到达片段。