解决 Material Design 中的 RecyclerView 滑动冲突问题**

阅读时长 13 分钟读完

随着 Material Design 在移动端应用开发中的广泛应用,RecyclerView 的使用也越来越普遍,但是在使用 RecyclerView 的时候可能会遇到一个常见的问题:滑动冲突。

滑动冲突的问题根源

滑动冲突,顾名思义,就是多个控件的滑动事件发生了冲突,导致出现诸如界面卡顿、滚动不流畅、错位等问题。 在 Material Design 中,RecyclerView 作为滚动条目列表的控件,在与其他可滑动控件(如 NestedScrollView 等)结合使用的过程中,也可能出现滑动冲突的问题。

滑动冲突的根本原因在于:两个可滑动控件同时响应相同的滑动事件,这时就需要在视觉和交互体验上进行设计权衡,使得不同控件在交互上各司其职,发挥各自的优势。

解决方案

解决 RecyclerView 滑动冲突的方法有多种,常见的有以下两种:

1.禁止一个控件的滑动事件

在 RecyclerView 和其他可滑动控件(如:NestedScrollView、ScrollView)共存的情况下,首先需要根据实际需要,决定哪个控件应该负责滑动事件的响应。如果你希望 RecyclerView 正常工作,让其他控件停止响应滑动,在处理 RecyclerView 时,可以添加以下代码:

该方法很简单,意味着使 RecyclerView 不再嵌套响应滑动。

2.控制滑动冲突

有时候需要让 RecyclerView 和其他可滑动控件同时响应滑动事件,这时就需要在代码中进行滑动交互的控制。

在实现 RecyclerView 和 NestedScrollView 滑动冲突时,只需要在布局文件中添加以下代码即可:

-- -------------------- ---- -------
-------------------------------------------
    -----------------------------------
    -------------------------------------
    
    -----------------------------
        ------------------------------------
        -----------------------------------
        --------------------------------------

---------------------------------------------

在 RecyclerView 的 Adapter 中重写 onAttachedToRecyclerView() 方法,实现以下代码:

-- -------------------- ---- -------
---------
------ ---- ------------------------------------- ------------- -
    ---------------------------------------------

    ----- -------------------------- ------------- - --------------------------------

    -- -------------- ---------- ------------------ -
        ----- ----------------- ----------------- - ------------------- --------------
        --------------------------------------- ---------------------------------- -
            ---------
            ------ --- --------------- --------- -
                ------ ------------------------- -- ----------- -- ------------------------- -- -----------
                        - -------------------------------- - --
            -
        ---
    -
-

这段代码中,我们通过 SpanSizeLookup 方法设置了 span size,以保证松散的布局和 Grid 布局的实现。然后,在处理内部事件时,我们就可以根据 RecyclerView 的滑动状态动态处理_nestedScrollView 的滑动事件。

-- -------------------- ---- -------
------------------------------------ ------------------------------- -

    ---------
    ------ ---- --------------------------------- ------------- --- --------- -
        ---------------------------------------- ----------

        -- --------- -- ------------------------------ -- -------- -- ----------------------------------- -
            ------------------------------------
        - ---- -
            --------------------------------------------------------------------
        -
    -

    ---------
    ------ ---- ----------------------- ------------- --- --- --- --- -
        ------------------------------ --- ----

        -- ----------------- -- ----- -
            -------------------------------------------- --- ----- ------
            ----------------------------------------- --- --- --- ------
        -
    -
---

可以看出,我们在这里是禁用了 NestedScrollView 的嵌套滑动响应,并根据 RecyclerView 的滑动状态,主动调用 startNestedScroll 和 stopNestedScroll 实现更细粒度的控制。

总结

以上就是我们解决 Material Design 中 RecyclerView 滑动冲突问题的两种常见方法,可以根据实际项目需求进行选择。除此之外,我们也可以通过自定义 SwipeRefreshLayout(以实现下拉刷新)来解决 RecyclerView 滑动冲突问题。无论采用哪种方法,我们需要做到的就是在不牺牲用户体验和操作需求的情况下,使得 RecyclerView 在和其他控件结合使用时能够最大化的发挥其优势特点,实现更好的交互体验和用户满意度。

示例代码

RecyclerView 和 NestedScrollView 嵌套及解决滑动冲突问题的示例代码,如下:

Activity 主代码:

-- -------------------- ---- -------
------ ----- ------------ ------- ----------------- -

    ------- ------------ -------------
    ------- ------------------- --------

    ---------
    --------- ---- --------------- ------------------- -
        -----------------------------------
        ---------------------------------------

        ------------ - ---------------------------------
        ------- - --- ------------------------- -----------------

        ------------------- ------------- - --- --------------------------
        ---------------------------------------------
        ---------------------------------

        ------------------------------------ ------------------------------- -

            ---------
            ------ ---- --------------------------------- ------------- --- --------- -
                ---------------------------------------- ----------

                -- --------- -- ------------------------------ -- -------- -- ----------------------------------- -
                    ------------------------------------
                - ---- -
                    --------------------------------------------------------------------
                -
            -

            ---------
            ------ ---- ----------------------- ------------- --- --- --- --- -
                ------------------------------ --- ----

                -- ----------------- -- ----- -
                    -------------------------------------------- --- ----- ------
                    ----------------------------------------- --- --- --- ------
                -
            -
        ---
    -

    ------- ------------ --------------- -
        ------------ ---- - --- --------------
        --- ---- - - -- - - --- ---- -
            -------------- - - -- - ----
        -
        ------ -----
    -
-

activity_main.xml:

-- -------------------- ---- -------
-------------------------------------------
    ------------------------------------
    -----------------------------------
    ------------------------------------
    ---------------------------
    -------------------------------------
    ------------------------------
    -------------------------------------------------------------

    -------------
        -----------------------------------
        ------------------------------------
        -------------------------------

        ---------
            ----------------------------
            -----------------------------------
            ------------------------------------
            ----------------------
            ---------------------
            -------------------------

        ---------------------------------------
            -------------------------------
            -----------------------------------
            ------------------------------------
            -----------------------------
            --------------------------------------
            -------------------------------------------
            ------------------------------------------

        ---------
            -----------------------------
            -----------------------------------
            ------------------------------------
            ----------------------
            ---------------------
            -------------------------

    ---------------
---------------------------------------------

RecyclerView List 适配器:

-- -------------------- ---- -------
------ ----- ------------------- ------- ---------------------------------------------------- -

    ------- ------- ---------
    ------- ------------ ------

    ------ --------------------------- -------- ------------ ----- -
        -------- - --------
        ----- - -----
    -

    ---------
    ------ ---------- ---------------------------- ------- --- --------- -
        ------ --- ----------------------------------------------------------------------------- ------- --------
    -

    ---------
    ------ ---- --------------------------- ------- --- --------- -
        ---------------------------------------------
    -

    ---------
    ------ --- -------------- -
        ------ -------------
    -

    ------ ----- ---------- ------- ----------------------- -

        -------- ---------

        --------------- --------- -
            ----------------
            -------- - ---------------------------------
        -
    -
-

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64e3ecc9f6b2d6eab3f515e4

纠错
反馈