ScrollView中的不可滚动ListView

75

我想要制作一个像这样的布局:

问题是,我不想让 ListViews 可滚动。我希望它们的高度尽可能高,并使整个屏幕可滚动。 如果我将 ListView 的高度设置为wrap_content,那行不通。唯一可行的方法是设置一个具体的高度-但我不知道有多少个项目在 ListView 中。

我知道不应该将 ListView 放在 ScrollView- 但我不想让 ListView 可滚动,只需显示所有项。

也许有更好的方法可以解决这个问题?

5个回答

162

您可以创建一个不可滚动的自定义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();    
    }
}

在您的布局资源文件中

<?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>

在Java文件中

创建一个自定义ListView对象,而不是普通的ListView。例如:
NonScrollListView non_scroll_list = (NonScrollListView) findViewById(R.id.lv_nonscroll_list);


2
当将此代码添加到现有代码库中时,只需修改XML文件即可,新类被添加后;大多数现有引用将实例转换为(ListView),仍然可以正常工作。 - rymo
你的逻辑对我很完美。但是当我进入包含非滚动列表视图的布局时,该列表显示在上面显示的详细信息之前。因此,用户被迫向下滚动以查看上面显示的详细信息。有什么解决办法吗? - user3013257
3
当 Android 显示包含 NonScrollListView 的布局时,父级 ScrollView 滚动到 NonScrollListView 的顶部,而不是滚动到 ScrollView 的顶部。(用户必须向上滚动才能查看在 NonScrollListView 之前的 ScrollView 内容。)这种情况发生在 EXACTLYAT_MOST 测量模式下,并且对于传递给 makeMeasureSpec() 的任何整数高度都是如此。 - kdbanman
4
@Dedaniyahirenkumar,如果将测量模式切换为“UNSPECIFIED”,则父级“ScrollView”保持滚动Y=零(预期行为)。显然,在这种情况下,“NonScrollListView”无法显示其全部内容。 - kdbanman
1
NonScrollListView在我上下滚动ScrollView时没有每次通知适配器,例如,当我在ListView中滚动并更改时间时,这个时间会改变,但是在这个NonScrollListView中,时间不会改变。从程序上讲,这个NonScrollListView没有回收它的视图。 - mostafa hashim
显示剩余2条评论

12

完全不需要使用 listview

如果你认真考虑一下,一个 listview 可以在你的情况下被一个 LinearLayout 替换。适配器Adapter将是相同的,但是,不要将适配器与listview相关联,而是在数据上使用for循环调用适配器的getView函数,并将检索到的视图添加到你的垂直 linearlayout 中。

然而,只有在你的列表中有少量项目且这些项目的显示表示形式不会消耗太多内存时才建议使用此方法。


我使用线性布局而不是列表视图,它可以工作,但是没有空间的项目看不到!我在父级中使用线性布局。 - Hossein
当您想要使用AbsListView.CHOICE_MODE_MULTIPLE_MODAL的优点时,LinearLayout并不是ListView的一个公平替代品。为了避免重复造轮子,请查看NonScrollListView解决方案。 - rymo
我认为用LinearLayout替换ListView似乎很合理,但您也会失去ListView固有的回收功能。尝试使用LinearLayout并通过动态充气其中大量视图来装载它。垃圾回收器会疯掉的。 - Joaquin Iurchuk

2

2017年最好的方法是使用带有NestedScrollViewRecyclerView

不需要任何技巧,它可以像您想要的那样开箱即用。


1
虽然那是一个不错的解决方案,但我认为这不是 OP 想要的,因为“问题在于我不想让 ListViews 可滚动”。 - Dan

0
我有一个简单的解决方案,如果您可以计算出您的项高度/宽度... 您只需要创建一个ListView的父LinearLayout,然后从Java中固定父高度。

enter image description here

假设您需要设计此视图... 现在父布局大小是从Java中定义的...
final LinearLayout parent=(LinearLayout)findViewById(R.id.parent);
final ListView  listview=(ListView)findViewById(R.id.listview);
parent.setLayoutParams(new LinearLayout.LayoutParams(parent.getLayoutParams().width, dpToPx( number_of_item_in_list * per_item_size_in_dp )));
//number_of_item_in_list is list side ~ listArray.size();
//per_item_size_in_dp = calculate item size in dp. Ex: 80dp

public static int dpToPx(int dp)
{
    return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}

就这些了 :)


0

嗨,有位名叫Mark Murphy的酷Android开发者,也被称为CommonsWare。他构建了一个非常有用的组件CWAC Merge Adapter,可以让你做你需要的事情。你需要动态添加视图,而不是从XML中添加;但考虑到你简单的UI,这应该不是问题。我在这种情况下使用它,当我不知道应该滚动哪种数据时。

如果你不想使用它(可能是出于许可证原因),你可以在那里放置一个单一的列表视图(而不是两个连续的列表视图),并重写getItemViewsCountgetItemViewTypegetView以提供上述布局。如果你在Google上搜索android listview different rows,你会找到有用的信息。例如this linkthis one

然而,我会选择合并适配器。


谢谢。问题在于我希望ImageView和TextView可以滚动 - 如果我向下滚动,它们会上移,ListView中的项目会出现。 - Dennis
然后使用合并适配器,在其中添加ImageView和TextView。即使有多个列表类型,您也可以通过将ImageView和TextView的视图类型设置为1和2来执行相同的操作。对于其余类型,您可以使用3和4。 - gunar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接