滚动视图内的Android列表视图

Zap*_*ica 258 android android-layout android-scrollview

我有一个android布局,其中包含scrollView许多元素.在scrollView我的底部有一个listView然后由适配器填充.

,我遇到的问题是,Android是不包括listViewscrollView作为scrollView已经具有滚动能够功能.我希望listView只要内容和主滚动视图是可滚动的.

我怎样才能实现这种行为?

这是我的主要布局:

<ScrollView
    android:id="@+id/scrollView1"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="2"
    android:fillViewport="true"
    android:gravity="top" >

    <LinearLayout
        android:id="@+id/foodItemActvity_linearLayout_fragments"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >
    </LinearLayout>

</ScrollView>
Run Code Online (Sandbox Code Playgroud)

然后我以编程方式将我的组件添加到具有id:的linearlayour foodItemActvity_linearLayout_fragments.下面是加载到该线性布局中的一个视图.这是给我卷轴问题的那个.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <TextView
       android:id="@+id/fragment_dds_review_textView_label"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="Reviews:"
       android:textAppearance="?android:attr/textAppearanceMedium" />

   <ListView
       android:id="@+id/fragment_dds_review_listView"
       android:layout_width="match_parent"
       android:layout_height="wrap_content">
   </ListView>
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)

我的适配器然后填写此列表视图.

当我点击主滚动视图时,这是来自android层次结构查看器的图像:

滚动视图中的Android列表视图

如您所见,它排除了评论listView.

我应该能够向下滚动页面并查看8条评论,但它只向我展示了那些3,我可以滚动查看评论的小部分.我想要一个全局页面滚动

ars*_*shu 549

最短的及最简单的方法一个滚动型中的ListView问题.

您不必在layout.xml文件中执行任何特殊操作,也不必处理父ScrollView上的任何内容.您只需处理子ListView.您还可以使用此代码在ScrollView中使用任何类型的子视图并执行Touch操作.

只需在java类中添加以下代码行:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.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.support.v7.widget.LinearLayoutCompat
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="16dp"
        android:paddingBottom="20dp">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Recycler View inside a Scroll View"
            android:textColor="@color/black"
            android:textSize="@dimen/_20sp"
            android:textStyle="bold" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="Below is a Recycler View as an example."
            android:textSize="16sp" />

        <android.support.v7.widget.RecyclerView
            android:id="@+id/recycler_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            app:layout_constraintTop_toBottomOf="@id/et_damaged_qty" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="This text automatically goes below the Recycler View."
            android:textSize="16sp" />
    </android.support.v7.widget.LinearLayoutCompat>
</android.support.v4.widget.NestedScrollView>
Run Code Online (Sandbox Code Playgroud)

如果将ListView放在ScrollView中,ListView不会拉伸到其完整高度.以下是解决此问题的方法.

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.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.support.v7.widget.LinearLayoutCompat
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="16dp"
        android:paddingBottom="20dp">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Recycler View inside a Scroll View"
            android:textColor="@color/black"
            android:textSize="@dimen/_20sp"
            android:textStyle="bold" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="Below is a Recycler View as an example."
            android:textSize="16sp" />

        <android.support.v7.widget.RecyclerView
            android:id="@+id/recycler_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            app:layout_constraintTop_toBottomOf="@id/et_damaged_qty" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="This text automatically goes below the Recycler View."
            android:textSize="16sp" />
    </android.support.v7.widget.LinearLayoutCompat>
</android.support.v4.widget.NestedScrollView>
Run Code Online (Sandbox Code Playgroud)

要使用此方法,只需在此方法中传递ListView:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.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.support.v7.widget.LinearLayoutCompat
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="16dp"
        android:paddingBottom="20dp">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Recycler View inside a Scroll View"
            android:textColor="@color/black"
            android:textSize="@dimen/_20sp"
            android:textStyle="bold" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="Below is a Recycler View as an example."
            android:textSize="16sp" />

        <android.support.v7.widget.RecyclerView
            android:id="@+id/recycler_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            app:layout_constraintTop_toBottomOf="@id/et_damaged_qty" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="This text automatically goes below the Recycler View."
            android:textSize="16sp" />
    </android.support.v7.widget.LinearLayoutCompat>
</android.support.v4.widget.NestedScrollView>
Run Code Online (Sandbox Code Playgroud)

用于与ExpandableListView一起使用 - 信用Benny

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.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.support.v7.widget.LinearLayoutCompat
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="16dp"
        android:paddingBottom="20dp">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Recycler View inside a Scroll View"
            android:textColor="@color/black"
            android:textSize="@dimen/_20sp"
            android:textStyle="bold" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="Below is a Recycler View as an example."
            android:textSize="16sp" />

        <android.support.v7.widget.RecyclerView
            android:id="@+id/recycler_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            app:layout_constraintTop_toBottomOf="@id/et_damaged_qty" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="This text automatically goes below the Recycler View."
            android:textSize="16sp" />
    </android.support.v7.widget.LinearLayoutCompat>
</android.support.v4.widget.NestedScrollView>
Run Code Online (Sandbox Code Playgroud)

对于具有可变项高度的ListView,请使用以下链接:

ScrollView中的ListView不在Android上滚动

让图书馆直接在您的代码中实施 - 信用Paolo Rotolo

https://github.com/PaoloRotolo/ExpandableHeightListView

  • 我发现这个解决方案在我的情况下完美运行,即支持列表 - 具有可变高度的项目 - http://stackoverflow.com/a/17503823/1433187 (4认同)
  • 请删除冗余的```requestLayout()``` - setLayoutParams方法已经做到了. (3认同)
  • FIX测量```view.measure(MeasureSpec.makeMeasureSpec(desiredWidth,MeasureSpec.AT_MOST),MeasureSpec.makeMeasureSpec(0,MeasureSpec.UNSPECIFIED));``` (2认同)
  • 我需要对 gridview 做同样的事情..有什么建议吗? (2认同)

eri*_*osg 221

答案很简单,我很惊讶这里还没有回答.

在列表本身上使用Header View或/和Footer View.不要ScrollView与一个ListView或任何可以滚动的东西混在一起.它的意思是用于页眉和页脚:)

基本上,将所有内容放在ListView上方,将其作为布局放入另一个.xml文件中,然后在代码中对其进行充气并将其作为标题视图添加到列表中.

View header = getLayoutInflater().inflate(R.layout.header, null);
View footer = getLayoutInflater().inflate(R.layout.footer, null);
listView.addHeaderView(header);
listView.addFooterView(footer);
Run Code Online (Sandbox Code Playgroud)

  • 如果添加标题视图,onListItemClick中的位置int参数将为+1.所以你必须处理它.(列表中的第一项将具有位置1,而不是0) (13认同)
  • @ericosg,但我不希望这就是为什么我在寻找解决方案. (2认同)
  • 我希望GridView有一个标题 (2认同)

小智 38

我知道它已经这么久了但我也遇到了这个问题,尝试了这个解决方案并且它正在运行.所以我想它也可以帮助其他人.

我在scrollView的布局xml上添加了android:fillViewport ="true".总的来说,我的ScrollView将是这样的.

<ScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/scrollView6" 
    android:fillViewport="true">
Run Code Online (Sandbox Code Playgroud)

它对我来说就像魔术一样.位于我的ScrollView内的ListView再次扩展到它的大小.

以下是ScrollView和ListView的完整示例代码.

<ScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/scrollView6" android:fillViewport="true">
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        ....
        <ListView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/lv_transList" android:layout_gravity="top"
            android:layout_marginTop="5dp"/>
        ....
    </LinearLayout>
</ScrollView>
Run Code Online (Sandbox Code Playgroud)

  • 它禁用ListView滚动行为,因此如果项目超过屏幕大小,则无法滚动列表视图. (4认同)
  • 它禁用ScrollView的滚动功能 (2认同)

Ded*_*mar 23

您创建不可滚动的自定义ListView

  public class NonScrollListView extends ListView {

            public NonScrollListView(Context context) {
                super(context);
            }
            public NonScrollListView(Context context, AttributeSet attrs) {
                super(context, attrs);
            }
            public NonScrollListView(Context context, AttributeSet attrs, int defStyle) {
                super(context, attrs, defStyle);
            }
            @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();    
            }
        }
Run Code Online (Sandbox Code Playgroud)

在您的布局资源文件中

     <?xml version="1.0" encoding="utf-8"?>
        <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fadingEdgeLength="0dp"
            android:fillViewport="true"
            android:overScrollMode="never"
            android:scrollbars="none" >

            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content" >

                <!-- com.Example Changed with your Package name -->

                <com.Example.NonScrollListView
                    android:id="@+id/lv_nonscroll_list"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content" >
                </com.Example.NonScrollListView>

                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_below="@+id/lv_nonscroll_list" >

                    <!-- Your another layout in scroll view -->

                </RelativeLayout>
            </RelativeLayout>

        </ScrollView>
Run Code Online (Sandbox Code Playgroud)

在Java文件中创建customListview的对象而不是ListView,如: NonScrollListView non_scroll_list =(NonScrollListView)findViewById(R.id.lv_nonscroll_list);


小智 8

    public static void setListViewHeightBasedOnChildren(ListView listView) {
    // ??ListView???Adapter
    ListAdapter listAdapter = listView.getAdapter();
    if (listAdapter == null) {
        return;
    }

    int totalHeight = 0;
    for (int i = 0, len = listAdapter.getCount(); i < len; i++) { // listAdapter.getCount()????????
        View listItem = listAdapter.getView(i, null, listView);
        listItem.measure(0, 0); // ????View ???
        totalHeight += listItem.getMeasuredHeight(); // ??????????
    }

    ViewGroup.LayoutParams params = listView.getLayoutParams();
    params.height = totalHeight
            + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
    // listView.getDividerHeight()?????????????
    // params.height??????ListView?????????
    listView.setLayoutParams(params);
}
Run Code Online (Sandbox Code Playgroud)

您可以在scrollview中将此代码用于listview


MV5*_*V53 8

您可以通过添加android:fillViewport="true"到ScrollView来解决它.

<ScrollView
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:background="@color/white"
      android:fillViewport="true"
      android:scrollbars="vertical">

<ListView
      android:id="@+id/statusList"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:animationCache="false"
      android:divider="@null"
      android:scrollingCache="false"
      android:smoothScrollbar="true" />

</ScrollView>
Run Code Online (Sandbox Code Playgroud)


在使用该属性之前,我的列表视图中只有一个子项可见.使用后,列表的所有行或子项都可见.


小智 6

如果您在代码中仅实现了ListView,则此代码将解决您的问题.

如果您使用RelativeLayout作为ListView子代码而不是此代码,则返回NullPointerException listItem.measure(0,0); ,因为RelativeLayout.And解决方案是将你的Relativelayout放在LinearLayout中,它会正常工作.

public static void setListViewHeightBasedOnChildren(ListView listView) {
    ListAdapter listAdapter = listView.getAdapter(); 
    if (listAdapter == null) {
        // pre-condition
        return;
    }

    int totalHeight = 0;
    for (int i = 0; i < listAdapter.getCount(); i++) {
        View listItem = listAdapter.getView(i, null, listView);
        listItem.measure(0, 0);
        totalHeight += listItem.getMeasuredHeight();
    }

    ViewGroup.LayoutParams params = listView.getLayoutParams();
    params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
    listView.setLayoutParams(params);
    listView.requestLayout();
}
Run Code Online (Sandbox Code Playgroud)


Ale*_*hak 5

我会留在这里以防万一有人会面临同样的问题.我不得不在ScrollView中放置一个ListView.由于多种原因,ListView with header不是一个选项.也不是使用LinearLayout而不是ListView的选项.所以我遵循了接受的解决方案,但它没有用,因为列表中的项目具有多行的复杂布局,每个listview项目的高度可变.高度测量不正确.解决方案是测量ListView Adapter的getView()方法中的每个项目.

@Override
public View getView(int position, View view, ViewGroup parent) {
    ViewHolder holder;
    if (view == null) {
        . . .
        view.setTag(holder);
    } else holder = (ViewHolder)view.getTag();
    . . .

    // measure ListView item (to solve 'ListView inside ScrollView' problem)
    view.measure(View.MeasureSpec.makeMeasureSpec(
                    View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED),
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
    return view;
}
Run Code Online (Sandbox Code Playgroud)


小智 5

您可以轻松地将 ListView 放入 ScrollView 中!只需要以编程方式更改 ListView 的高度,如下所示:

    ViewGroup.LayoutParams listViewParams = (ViewGroup.LayoutParams)listView.getLayoutParams();
    listViewParams.height = 400;
    listView.requestLayout();
Run Code Online (Sandbox Code Playgroud)

这工作得很好!

  • 这就是 [已接受的答案](http://stackoverflow.com/a/19311197/1864167) 所做的,但不是神奇地确定它是 400,而是计算确切的高度。这样你就不用猜了。 (3认同)

Sib*_*bin 5

不要在Parent ScrollView中执行任何操作。仅对子级ListView执行此操作。一切都会完美运行。

mListView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                mScrollView.requestDisallowInterceptTouchEvent(true);
               int action = event.getActionMasked();
                switch (action) {
                    case MotionEvent.ACTION_UP:
                        mScrollView.requestDisallowInterceptTouchEvent(false);
                        break;
                }
                return false;
            }
        });
Run Code Online (Sandbox Code Playgroud)

  • 这应该是一个可以接受的答案。它简单又聪明。只需在触摸列表视图时禁用滚动视图,并在抬起手指时再次启用它 (3认同)

Hir*_*tel 5

经过大量研发完成:

fragment_one.xml 应如下所示:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/scrollViewParent"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="400dip" >

            <ListView
                android:id="@+id/listView"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />

            <View
                android:id="@+id/customView"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:background="@android:color/transparent" />
        </RelativeLayout>

        <!-- Your other elements are here -->

    </LinearLayout>

</ScrollView>
Run Code Online (Sandbox Code Playgroud)

FragmentOne.java 的 Java 类如下所示:

private ListView listView;
private View customView
Run Code Online (Sandbox Code Playgroud)

创建视图

listView = (ListView) rootView.findViewById(R.id.listView);
scrollViewParent = (ScrollView)rootView.findViewById(R.id.scrollViewParent);
customView = (View)rootView.findViewById(R.id.customView);

customView.setOnTouchListener(new View.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.
                        scrollViewParent.requestDisallowInterceptTouchEvent(true);
                        // Disable touch on transparent view
                        return false;

                    case MotionEvent.ACTION_UP:
                        // Allow ScrollView to intercept touch events.
                        scrollViewParent.requestDisallowInterceptTouchEvent(false);
                        return true;

                    case MotionEvent.ACTION_MOVE:
                        scrollViewParent.requestDisallowInterceptTouchEvent(true);
                        return false;

                    default:
                        return true;
                }
            }
        });
Run Code Online (Sandbox Code Playgroud)