【问题标题】:ListView nested scrolling on API<21API<21 上的 ListView 嵌套滚动
【发布时间】:2015-12-24 23:52:05
【问题描述】:

标题很清楚。我有这个布局:

_________________
|_______________| <- Toolbar    
|___|___|___|___| <- Tablayout
|               |
|               |
|   ViewPager   |
|               |
|_______________|

工具栏和标签布局都在AppBarLayout 内,所以我可以使用滚动标志来隐藏工具栏滚动到顶部。问题是这只适用于支持嵌套滚动的视图。大多数标签——我的意思是,大部分页面——都是support.v4.NestedScrollViews,所以没关系;其他人是(并且需要)ListViews。

从 Lollipop 开始,我只需将 android:nestedScrollingEnabled="true" 添加到列表视图中,工具栏就会在滚动时正确隐藏。

但是,在 APICoordinatorLayout 中的一些测量错误,列表中的最后一项被隐藏了:listview 的行为就像它拥有工具栏当前占用的空间。

解决方案:

  • 切换到RecyclerView,它确实支持嵌套滚动:我不能,因为我需要使用仅适用于适配器视图且无法替换的外部库适配器(即@ 987654328@);

  • 扩展 ListView 并实现嵌套滚动:看起来有点复杂;

  • 扩展 ListView 并实施一些解决方法,例如测量内容以避免最后一项问题或(和)自定义行为以使工具栏隐藏:看起来也很复杂;

  • 使用一些布局技巧:找不到。

有什么帮助吗?

例如,我(拼命地)尝试过:

<android.support.v4.widget.NestedScrollView
    android:nestedScrollingEnabled="true"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ListView
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </ListView>

</android.support.v4.widget.NestedScrollView>

但是这样ListView 不会被布置为match_parent。我得到一个小高度的小视图,页面的其余部分是空的。

【问题讨论】:

    标签: android android-listview android-support-library android-design-library android-appbarlayout


    【解决方案1】:

    不幸的是,没有办法让嵌套滚动在 ListView 上工作 - 否则它不需要在 API 21 中进行的修改。

    您会注意到当前的Parse SDK 实际上已经完全删除了ParseQueryAdapter。鉴于此,开始使用Parse query APIs directly 构建您自己的基于RecyclerView 的适配器可能是有意义的。

    【讨论】:

    • 我不在最后一个版本上,但我记得该类在公共 API 中没有列出很长时间。不过,谢谢你“你不能”——我花了几个小时处理 NestedScrolling 接口。
    • “没有办法让嵌套滚动在 ListView 上工作”。有 ViewCompat.setNestedScrollingEnabled(ListView, boolean);
    • @Dogcat - 在 API 21 之前什么都不做。它只是让您不必检查 API 级别。
    • @Dogcat - pre-API 21 source code 需要视图来实现支持库的NestedScrollingChild 接口,而像ListView 这样的框架类永远不会这样做。它仅在 API 21+ 上调用框架 setNestedScrollingEnabledListView 确实实现了该框架。
    【解决方案2】:

    对于那些对特定ParseQueryAdapter 问题感兴趣的人,

    【讨论】:

      【解决方案3】:

      我实际上是Xamarin 开发人员,所以我无法测试这是否适用于这种特殊情况,但我找到了an answer which helped me in Xamarin,所以我要分享它:

      我找到了一个很好的解决方案,可以滚动 ListView 没有问题:

      ListView lv = (ListView)findViewById(R.id.myListView);  // your
      listview inside scrollview lv.setOnTouchListener(new
      ListView.OnTouchListener() {
          @Override
          public boolean onTouch(View v, MotionEvent event) {
              int action = event.getAction();
              switch (action) {
              case MotionEvent.ACTION_DOWN:
                  // Disallow ScrollView to intercept touch events.
                  v.getParent().requestDisallowInterceptTouchEvent(true);
                  break;
      
              case MotionEvent.ACTION_UP:
                  // Allow ScrollView to intercept touch events.
                  v.getParent().requestDisallowInterceptTouchEvent(false);
                  break;
              }
      
              // Handle ListView touch events.
              v.onTouchEvent(event);
              return true;
          }
      });
      

      这样做是禁用 ScrollView 上的 TouchEvents 并使 ListView 拦截它们。它很简单,而且一直有效。

      如果这不起作用,请告诉我,以便我删除此答案。但也许它对任何人都有帮助,因为我也发现了这个问题,但似乎没有解决方案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-12-30
        • 2020-02-13
        • 2021-11-06
        • 1970-01-01
        • 2020-05-15
        • 1970-01-01
        • 1970-01-01
        • 2019-03-04
        相关资源
        最近更新 更多