我发现了以下问题:Android:FragmentActivity 内的 FragmentActivity(NavigationBar 中的 ScrollView) https://stackoverflow.com/q/11761454/787399。然而,我的这个问题是关于如何使用事务来显示片段以及以安全的方式启用滑动手势检测。
注意:我发布的答案中有一个链接(这也有一种使用事务在容器中显示片段的有效方法,包括两种场景)。请看一下。
我已经尝试了一些方法,但是通过使用支持 ViewPager 的片段,而不是嵌套:
细节:https://moqups.com/[电子邮件受保护]/lc0ZOERO/p:a5d7b55eb https://moqups.com/abhsax130778@gmail.com/lc0ZOERO/p:a5d7b55eb
- 使用自定义 ViewPager 使用 onTouchEvent 和 onInterceptTouchEvent 禁用默认滑动。
- 声明的 FragmentStatePagerAdapter 提供了一个片段列表,每个片段都显示在每个选项卡中。
- 在具有此 ViewPager 的 main_activity 的 main_layout 中声明 Fragment。
想法是当单击 ViewPager_fragment 上的按钮以及用户按回车键时显示 Activity_fragments
按钮,然后使用添加时的返回堆栈事务再次显示默认的 ViewPager_fragment,并将它们弹出到活动的 BackPressed 上。因此,我还维护自定义后堆栈,以在后堆栈弹出事务时显示/隐藏 Activity_fragments。
现在我想要实现的是仅使用向右[从左到右]滑动的滑动手势来完成上面的第三点。
我为此使用了 GestureListener 和 SimpleOnGestureListener 以及活动的 OnTouchEvent 。
我面临的问题是:
此手势适用于片段下方的活动屏幕部分和活动部分。
我想要手势工作
- 在布局中有多个视图的片段区域上。
- 仅在左右方向上。
- 仅从 Activity_fragment 到 ViewPager 的选项卡片段的行为类似于历史导航,就像 onBakPressed/onKeyDown 中已经完成的那样
使用后退堆栈弹出窗口和我的自定义后退堆栈实现。
我尝试了以下课程,并在布局中更改了我的活动片段,如下所示。
我的手势和触摸监听器通过框架布局进行了扩展:
public class OnSwipeTouchListener extends FrameLayout {
private final GestureDetector gestureDetector;
private static final String TAG = "OnSwipeTouchListener";
private Context context;
public OnSwipeTouchListener(Context context, AttributeSet attrs) {
super(context, attrs);
this.context=context;
gestureDetector = new GestureDetector(context, new GestureListener());
setClickable(true);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
gestureDetector.onTouchEvent(motionEvent);
return super.onTouchEvent(event);
}
private final class GestureListener extends SimpleOnGestureListener {
private static final int SWIPE_THRESHOLD = 100;
private static final int SWIPE_VELOCITY_THRESHOLD = 100;
@Override
public boolean onDown(MotionEvent e) {
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
boolean result = false;
try {
float diffY = e2.getY() - e1.getY();
float diffX = e2.getX() - e1.getX();
if (Math.abs(diffX) > Math.abs(diffY)) {
if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
if (diffX > 0) {
onSwipeRight();
} else {
onSwipeLeft();
}
}
} else {
if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
if (diffY > 0) {
onSwipeBottom();
} else {
onSwipeTop();
}
}
}
} catch (Exception exception) {
//see that e1 is null
}
return result;
}
}
public void onSwipeRight() {
///manage my back stack history here.
}
public void onSwipeLeft() {
}
public void onSwipeTop() {
}
public void onSwipeBottom() {
}
}
然后将框架布局更改为此类引用:
<path.to.my.package.OnSwipeTouchListener
android:id="@+id/activity_frag_frame_layout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="invisible" >
<fragment
android:id="@+id/activity_frag1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
class="path.to.my.package.fragments.Activity_Frag1"
android:tag="act_frag1" />
</path.to.my.package.OnSwipeTouchListener>
它对我帮助不大,所以它应该可以帮助你找到解决方案。其中一个片段中有一个 searchView 停止工作,并且没有点击工作。
如果您得到了我想要实现的目标,请在这方面提供帮助。
更新1:
在 onTouchEvent 和 onInterceptTouchEvent 中返回 true 具有所需的效果,但它会阻止 SearchView 所在片段中的单击,而在存在的可单击视图中则不会发生单击。只有滑动才有效。更新:在我的最新文章中:我还完全放弃了事务后台堆栈的使用,因为我依赖于自定义后台堆栈,在其中维护所有选项卡的导航历史记录。我使用 ViewPager 和 FragmentStatePagerAdapter 提供的 setCurrentTab 和 onTabSelected 方法来执行此操作。
更新2:
这个很难实现:
检查哪些事件需要被拦截以及哪些事件要传递给子视图:http://developer.android.com/training/gestures/viewgroup.html http://developer.android.com/training/gestures/viewgroup.html
更新3:
在我的活动布局中,有一个视图分页器,在它下面的每个框架布局中,都有一个片段。
当您启动应用程序时,ViewPager 在第一个选项卡中显示片段。
单击此片段上的按钮时,将显示视图寻呼机下方框架布局中的片段之一,并将其添加到我的自定义后堆栈中。
当按下返回键时,该片段再次隐藏,以在视图分页器中显示选项卡片段。以上每一项都完成了。只有我想要从左到右的滑动手势起作用,我发现我可以通过拦截触摸事件来做到这一点。
但它根本没有做到这一点当我返回 true 时,
仅滑动手势有效,否则该操作将被取消并且
对该片段的点击有效。