在片段级别与ViewPager一起应用了滑动手势,但禁用了默认滑动

阿比纳夫·萨克塞纳(Abhinav Saxena)

我发现以下问题:Android:FragmentActivity内的FragmentActivity(NavigationBar中的ScrollView)但是,我的问题是关于如何使用事务显示片段以及以安全方式启用滑动手势检测的问题。注意:我发布的答案中有一个链接(这也是使用事务显示容器中片段的有效方法,包括两种情况)。请看。我已经尝试过一些事情,但是通过使用支持ViewPager而不是嵌套的片段:

详细信息:https : //moqups.com/[email protected]/lc0ZOERO/p : a5d7b55eb

  1. 使用onTouchEvent和使用自定义ViewPager的onInterceptTouchEvent禁用默认的滑动。
  2. 声明的FragmentStatePagerAdapter提供了一个片段列表,每个片段显示在每个选项卡中。
  3. 在main_activity的main_layout中声明片段,该片段旁边有此ViewPager。想法是在单击ViewPager_fragment上的按钮时,当用户按下返回按钮时,显示activity_fragments,然后使用添加时的向后堆栈事务再次显示默认的ViewPager_fragment,并在活动的BackPressed上将其弹出。因此,我还将维护我的自定义后台堆栈,以在后台堆栈弹出事务时显示/隐藏activity_fragments。

现在,我要实现的是仅对右[从左到右]滑动使用滑动手势来完成上面的第三点。

我为此使用了GestureListener和SimpleOnGestureListener以及活动的OnTouchEvent。

我面临的问题是:

此手势在活动屏幕上位于片段下方的部分和活动的一部分上起作用。我想要手势工作

  1. 在“片段”区域中,该区域的布局具有多个视图。
  2. 仅在左右方向上。
  3. 只有从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

更新3:

  1. 在我的活动布局中,有一个视图寻呼机,在它下面的每个框架布局中,都有一个片段。

  2. 启动应用程序时,ViewPager在第一个选项卡中显示片段。

  3. 单击此片段上的按钮时,将显示视图分页器下面的帧布局中的一个片段,并将其添加到我的自定义后台堆栈中。

  4. 当按下返回键时,此片段再次被隐藏,以在视图寻呼机中显示选项卡片段。以上所有步骤均已完成。只有我想要从左到右的滑动手势才能工作,我发现可以通过拦截触摸事件来做到这一点。但它根本不执行此操作。当我返回true时,只有滑动手势有效,否则,该操作将被取消并且对该片段的单击有效。

阿比纳夫·萨克塞纳(Abhinav Saxena)

我在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()。在这里,您不使用事务,但是您可以使用]。

  1. 使用Fragment.instantiate()初始化片段而不是构造函数。
  2. 使用侦听器更新/删除片段onCreateView和onDestroy的实例引用(从用于引用它们的集合中)。
  3. 使用getView()获取片段的根视图(在任何位置以及更新功能上)。
  4. 不要跟踪实例,实际上应尽可能避免使用静态指针。
  5. 使用getSupportFragment而不是在视图寻呼机适配器或其他地方保留FragmentManager的引用。
  6. 在事务隐藏视图上使用attach detatch可以除去Fragment的根视图上的子视图,然后重新初始化。这是因为一次只需要一个片段可见,而另一个则需要分离。因此,按需重新连接。
  7. getActivity()或getApplicationContext()(适用时),而不是保留全局变量以保留对上下文的引用。
  8. onConfiguration更改(方向,键盘,调整大小):在活动中执行并将其传递给管理它的活动片段。重要说明:如果确实要使用片段进行事务处理,请不要在布局中声明它们。在添加片段事务中提供容器(布局)ID。
  9. 片段事务应在事件调用中完成,而不是在其他任何地方进行,并且此类事件不应重复。这样可以防止非法参数异常。
  10. 有一个ViewPager方法,您不必使用Fragments,而是可以使用Views或ViewGroups。这将替换片段的嵌套。
  11. 检测片段的级别,这意味着如果您希望片段“ B”替换现有的片段“ A”,并且当您想在按回“ B”时返回以显示片段“ A”时,请将该事务放回去堆。

提示:添加滑动功能时请多加注意,因为还有其他可单击的视图。在RootView上使用拦截触摸轻扫,返回false,但分析触摸。


还有一件事:您应该观察到一次在一个容器中放置一个片段可以解决另一个问题:如果有两个片段,一个在另一个容器的顶部,则来自一个片段的点击将转到下面的另一个片段。因此,隐藏或替换一次只能有一个片段。Back-Stack帮助维护导航级别,并且在更改或更新配置时,尝试更新目标活动片段的相同实例,而不是进行事务处理,因为这会改变导航片段的顺序。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类常见问题

禁用在Android中打开导航抽屉的滑动手势

来自分类Dev

默认情况下,滑动片段手势与ViewPager一起应用于片段级别

来自分类Dev

将滑动手势添加到UITableView

来自分类Dev

Windows 8应用商店应用程序-滑动手势即可导航

来自分类Dev

滑动菜单:禁用滑动手势

来自分类Dev

UISplitViewController滑动手势会干扰其他滑动手势

来自分类Dev

在UIPageViewController中禁用滑动手势

来自分类Dev

禁用特定片段的滑动手势(导航抽屉)

来自分类Dev

iOS WebView滑动手势识别和缩放

来自分类Dev

如何在iOS 8的UINavigationController中禁用向后滑动手势?

来自分类Dev

统一在Android上滑动手势

来自分类Dev

在Windows Phone 8.1枢轴控件中禁用滑动手势

来自分类Dev

iOS UIWebView-如何禁用网页的滑动手势(例如,javaScript等)

来自分类Dev

NSPageController,停用滑动手势

来自分类Dev

屏幕边缘滑动手势的水平uitableview

来自分类Dev

Xamarin形式向左/向右滑动手势

来自分类Dev

如何在同一视图上交替使用平移手势和滑动手势?

来自分类Dev

启用禁用滑动手势快速

来自分类Dev

如何在React Native导航器中禁用向后滑动手势

来自分类Dev

用户滑动手势即可滑动按钮

来自分类Dev

Tab +滑动手势,自定义网格视图,片段

来自分类Dev

在UIButton中滑动手势

来自分类Dev

如何添加滑动手势?

来自分类Dev

SWRevealViewController滑动手势会导致应用崩溃

来自分类Dev

启用禁用滑动手势迅速

来自分类Dev

如何检测屏幕上的滑动手势并将其传递到底部的小ViewPager?

来自分类Dev

如何在React Native导航器中禁用向后滑动手势

来自分类Dev

滑动手势问题

来自分类Dev

无法识别滑动手势

Related 相关文章

热门标签

归档