滑动手势与 ViewPager 一起应用于 Fragment 级别,并且默认禁用滑动

2024-02-05

我发现了以下问题: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

  1. 使用自定义 ViewPager 使用 onTouchEvent 和 onInterceptTouchEvent 禁用默认滑动。
  2. 声明的 FragmentStatePagerAdapter 提供了一个片段列表,每个片段都显示在每个选项卡中。
  3. 在具有此 ViewPager 的 main_activity 的 main_layout 中声明 Fragment。 想法是当单击 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 http://developer.android.com/training/gestures/viewgroup.html

更新3:

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

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

  3. 单击此片段上的按钮时,将显示视图寻呼机下方框架布局中的片段之一,并将其​​添加到我的自定义后堆栈中。

  4. 当按下返回键时,该片段再次隐藏,以在视图分页器中显示选项卡片段。以上每一项都完成了。只有我想要从左到右的滑动手势起作用,我发现我可以通过拦截触摸事件来做到这一点。 但它根本没有做到这一点当我返回 true 时, 仅滑动手势有效,否则该操作将被取消并且 对该片段的点击有效。


我在中提到过这个答案http://mobi-app-dev.blogspot.in/2014/01/android-transactions.html http://mobi-app-dev.blogspot.in/2014/01/android-transactions.html.

检查哪些事件需要被拦截以及哪些事件要传递给子视图:http://developer.android.com/training/gestures/viewgroup.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;
    }

以下是我在活动中使用 Fragment 时遵循的一些提示:

有效管理碎片的交易:

[注意:如果您使用 FragmentStatePagerAdapter,您可以将一个片段替换为您用作此适配器数据的片段列表中特定索引处的另一个片段,就像您位于同一选项卡中一样但其内容已更改,但未更改选项卡。然后使用notifyDataSetChanged()。在这里您不使用事务,但否则您会使用]。

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

提示:添加滑动功能时要小心,因为还有其他可点击的视图。 在根视图上拦截触摸滑动,返回 false 但分析触摸。


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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

滑动手势与 ViewPager 一起应用于 Fragment 级别,并且默认禁用滑动 的相关文章

随机推荐

  • 使用 NSOpenpanel 和 NSfilemanager 查找目录内容

    我是 Objective C 的新手 所以请原谅我缺乏知识 我这里有一段代码 我似乎无法正常工作 我想做的是在单击按钮时显示一个目录选择面板 一旦用户选择一个目录 我想创建一个包含该目录中所有内容的数组 最终我想使用这个数组将子目录和文件
  • Python 中的“或”条件问题[重复]

    这个问题在这里已经有答案了 我正在学习Python 但遇到了一些问题 在我正在学习的课程中看到类似的内容后 我想出了这个简短的脚本 我之前已经成功地使用了 or 和 if 这里没有显示太多 由于某种原因 我似乎无法让它工作 test raw
  • 尝试上传 Ionic 应用程序时收到“抱歉!配置的后端(专业版)不知道 ionic 上传”

    我正在尝试将我构建的应用程序上传到我的 Ionic Pro 帐户 我已链接我的帐户并添加了 SSH 密钥 但运行 ionic upload 后出现此错误 错误 抱歉 配置的后端 专业版 不知道离子上传 这是我的离子信息 cli 包 home
  • 错误 C2432 非法引用 __asm 的“第二个操作数”中的 16 位数据

    在 Visual Studio 中 当我用 C 编译 asm 时 我收到此错误 有人知道这段代码有什么问题吗 我尝试了一切 但没有任何效果 我正在尝试在装配中实现冒泡排序 unsigned short i 0 unsigned short
  • 如何删除 numpy 数组中的列?

    假设我们有一个 5x4 矩阵 我们只需要删除第一个维度 我们怎样才能做到这一点numpy array 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 dtype float32 I tri
  • R 中 xtable 的变量概述

    我想知道是否可以创建一个xtable从命令str x 从您使用的变量中获得概览 如果要向某人介绍数据集 这将是一个很好的功能 但自己创建它会很烦人 所以我尝试的是做一个xtable像这样 str cars require xtable xt
  • 如何使用另一个 bash 脚本创建一个 bash 脚本? [复制]

    这个问题在这里已经有答案了 我正在创建一个仅运行一次的 bash 脚本 但之后它将创建另一个 bash 脚本 我尝试使用 CAT EOT 但问题是 它不是在新 bash 中复制 粘贴文本 而是 执行 其中的所有变量 例如 而不是写 date
  • 使用 Python 映射 Windows 驱动器的最佳方法是什么?

    使用 Python 将网络共享映射到 Windows 驱动器的最佳方法是什么 此共享还需要用户名和密码 基于 Anon 的建议 Drive letter M Shared drive path shared folder Username
  • 库里-霍华德同构产生的最有趣的等价是什么?

    我来到了库里 霍华德同构 http en wikipedia org wiki Curry E2 80 93Howard correspondence我的编程生涯相对较晚 也许这使得我对它完全着迷 这意味着对于每个编程概念 形式逻辑中都存在
  • 我们可以在

    标签内添加 吗?

    使用方法是否正确 span 标签内的 h1 tag h1 span class boardit Portfolio span h1 我知道我们可以用这种方式编写它 并且我也在我自己的网站中遵循以下语法 h1 class boardit sp

  • 在mysql批处理中运行多个sql文件

    要运行单个文件 您可以在 mysql 中运行 文件名 或者你可以在 mysql 之外运行 mysql 我有一个 sql 文件目录 所以我尝试使用通配符一次性运行它们 sql 但它不起作用 有任何想法吗 假设您使用的是 bash cat sq
  • 为什么我不能将 case 对象用作多态类型

    以下代码无法编译 case object O trait Show A def show a A String class OShow extends Show O override def show a O String ahoy 编译错
  • linux 是否提供了保证在堆栈低端以下的不可访问的内存区域?

    Linux 是否在堆栈下端以下提供了一个具有保证最小大小的不可访问的内存区域 如果存在这样的保证最小尺寸 它是什么呢 或者换句话说 我什么时候应该开始担心alloca 或者给我指向有效的非堆栈内存的指针 As the alloca 手册页
  • Google 地图 [API] 视图在我的移动设备上呈灰色

    大家好 我真的需要你们的帮助 我已阅读此链接上有关如何使用 Google API 的说明 https developers google com maps documentation android start https develope
  • jQuery - 使用 $.post 接收 $_FILES 数组

    我正在尝试通过 jQuery 提交表单 我的表单包含必须上传的字段和文件 它属于类型ENCTYPE multipart form data 我可以使用以下方式接收所有字段值 post myForm serialize 但我如何接收 FILE
  • C++:作为成员的抽象类

    我有一个关于风格的问题 我有一个类 在我的例子中是一个选项 它取决于外生对象的价值 利率 我的目标是为外生对象 Rate 创建一个抽象基类 以便我可以构造变体 例如 SimulatedRate 或 ConstantRate 它们将在我的依赖
  • CGWindowListCopyWindowInfo、kCGWindowLayer 和窗口级别

    The CGWindowLevel h文件定义了用于设置窗口级别的常量 可用作窗口级别的最大值为 20 但是 如果您使用以下调用检索窗口列表CGWindowListCopyWindowInfo 您可以观察到kCGWindowLayer大于
  • Ansible:如何禁用但正在运行的服务?

    我想遍历很多主机并获取所有手动启动的服务 systemctl start xxxx 而无需先启用 systemctl enable xxxx 反之亦然所有已禁用 systemctldisable xxxx 但仍在运行的服务 因为还没有停止
  • cookie 和缓存的过期值如何工作?

    过期值总是让我感到困惑 因为客户端的时间设置可能与服务器的时间设置完全不同 我想知道幕后发生了什么 假设我的服务器的时区是 GMT 1 客户端的时区是 GMT 2 如果我现在创建一个带有过期值的 cookie current timesta
  • 滑动手势与 ViewPager 一起应用于 Fragment 级别,并且默认禁用滑动

    我发现了以下问题 Android FragmentActivity 内的 FragmentActivity NavigationBar 中的 ScrollView https stackoverflow com q 11761454 787