我发现了以下问题: Android: FragmentActivity in FragmentActivity (Scrollview in Navigationbar) 。然而,我的这个问题是关于如何使用事务来显示片段以及以安全的方式启用滑动手势检测。 注意:我发布的答案中有一个链接(这也是使用事务在容器中显示片段的有效方法,包括两个方案)。请看那个。 我已经尝试了一些问题,但是使用支持ViewPager的片段,而不是嵌套:
详细信息:https://moqups.com/abhsax130778@gmail.com/lc0ZOERO/p:a5d7b55eb
现在我想要实现的是使用滑动手势进行上面的第三点,仅用于从右向左滑动。
我已经使用了GestureListener和SimpleOnGestureListener以及activity的OnTouchEvent。
我面临的问题是:
此动作适用于活动屏幕的位于片段下方和活动部分的部分。 我想要手势
我尝试了以下类,并在这样的布局中更改了我的活动片段。
My Gesture和Touch监听器扩展了框架布局:
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
更新3:
在我的活动布局中,有一个视图寻呼机,并在其下方的每个帧布局中 有一个片段。
启动应用时,viewPager会在第一个标签中显示该片段。
单击此片段上的某个按钮时,其中一个片段 显示viewpager下方的framelayouts并将其添加到我的自定义backstack中。
按下返回键时,将再次隐藏此片段以显示选项卡片段 viewPager。以上所有内容都已完成。只有我想要滑动手势 从左到右工作,我发现我可以通过拦截触摸事件来做到这一点。 但它根本不会这样做当我回归真实, 只有滑动手势有效,否则此动作将被取消 点击此片段的工作。
答案 0 :(得分:1)
我在http://mobi-app-dev.blogspot.in/2014/01/android-transactions.html中提到了这个答案。
检查哪些事件需要被截获以及哪些事件要传递给子视图:http://developer.android.com/training/gestures/viewgroup.html
而不是在框架布局中使用我的滑动手势监听器 哪些碎片附着, 现在我在相对布局上使用它,它是根的视图 片段。
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
boolean intercepted = super.onInterceptTouchEvent(event);
// In general, we don't want to intercept touch events. They should be
// handled by the child view.
gestureDetector.onTouchEvent(event);
return false;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean touched = super.onTouchEvent(event);
gestureDetector.onTouchEvent(event);
return touched;
}
以下是我在活动中使用片段时所遵循的一些提示:
[注意:如果您正在使用FragmentStatePagerAdapter,您可以使用您所使用的方式将片段替换为您用作此适配器数据的片段列表中特定索引处的另一个片段。相同的选项卡,但其内容更改而不更改选项卡。然后使用notifyDataSetChanged()。在这里你不使用交易,但你不这样做。
提示:添加滑动功能时请小心,因为还有其他可点击的视图。 在RootView上使用拦截触摸进行滑动,返回false,但会分析触摸。
还有一件事:您应该观察到,一次在一个容器中放置一个片段可以解决另一个问题:如果有两个片段,一个位于另一个片段的顶部,一个片段的点击将转到另一个片段下面。所以隐藏或替换一次只有一个片段。 Back-Stack有助于维护导航级别,并且在配置更改或更新时,尝试更新目标活动片段的相同实例,而不是执行事务,因为这会更改导航的片段的顺序。