【问题标题】:Android: Scroll whole fragment with ListView insideAndroid:滚动整个片段,里面有 ListView
【发布时间】:2020-12-01 11:36:23
【问题描述】:

我的片段布局文件中有以下结构:

- ScrollView
  - ConstraintLayout
    - CardView
      - *some stuff here*
    - CardView
      - ListView
        - *list header*
        - *list items generated with a custom adapter*

如果我删除外部ScrollView,我可以看到ListView 的全部内容,如果它大于第二个CardView 的剩余空间,我可以滚动它。第一个CardView 保持不变,但第二个的内容是可滚动的。

但是,我想滚动整个片段。我希望第二个CardView 扩展并包含整个ListView,如果我向上或向下滚动,第一个也会移动。

我尝试了几种高度设置组合。没有必要向您展示我的实际布局 XML,因为它一团糟。我想要一张白纸。有没有可能实现?

编辑:

我知道ListView 本身就是一个滚动容器,但我认为滚动整个东西是很常见的需求,所以我不明白为什么让它工作这么难。

【问题讨论】:

  • 如果您将 ScrollView 替换为 NestedScrollView,也许它会起作用。
  • @Arantik 我试过了。没有运气。
  • @Arantik 原来,NestedScrollView 是解决方案的一部分。

标签: android android-listview


【解决方案1】:

好的,综合多个答案后,我得到了我需要的解决方案。

首先

我需要使用NestedScrollView 而不是常规的ScrollView

它解决了两个滚动容器(ScrollViewListView)之间的冲突。

参考:Android: ScrollView vs NestedScrollView

注意:我的列表内容是动态的,因此可能太短而无法填满剩余空间。我必须在NestedScrollView 上设置android:fillViewport="true"。如果列表长于剩余空间,则不会造成任何麻烦。

layout.xml

<?xml version="1.0" encoding="utf-8"?>

<androidx.core.widget.NestedScrollView 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.cardview.widget.CardView
            android:id="@+id/card1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
        <!-- NOTE: constraints properties are missing from here for easier reading -->

            <!-- card content here -->

        </androidx.cardview.widget.CardView>

        <androidx.cardview.widget.CardView
            android:id="@+id/card2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
        <!-- NOTE: constraints properties are missing from here for easier reading -->

            <ListView
                android:id="@+id/list"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
            <!-- NOTE: this will change in step 3 -->

        </androidx.cardview.widget.CardView>

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.core.widget.NestedScrollView>

第二

按照上述步骤,ListView 将折叠到其第一个项目的高度。为了解决这个问题,我需要从ListView 创建一个子类并覆盖它的onMeasure() 方法,这样它就可以在运行时计算出合适的高度。

参考:Android - NestedScrollView which contains ExpandableListView doesn't scroll when expanded

NonScrollListView.java

package my.package.name

import ...

public class NonScrollListView extends ListView {
    
    // NOTE: right click -> create constructors matching super

    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
        ViewGroup.LayoutParams params = getLayoutParams();
        params.height = getMeasuredHeight();
    }
}

第三

我需要在我的布局 XML 中使用我的自定义视图而不是常规的 ListView

layout.xml摘录

<my.package.name.NonScrollListView
    android:id="@+id/list"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

这样我就成功了。即使我点击ListView 区域,两张卡片也会在滚动时一起移动。

我不知道它是否会导致列表很长的性能问题,因为我最多包含几十个项目,但我在低端 Galaxy A20e 上没有问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多