嵌套的 ListViews 没有扩展到全高
Posted
技术标签:
【中文标题】嵌套的 ListViews 没有扩展到全高【英文标题】:Nested ListViews not expanding to full height 【发布时间】:2016-05-14 05:57:41 【问题描述】:我一直在尝试在 SO 和 Google 上搜索一段时间,但不能完全正确。我有一个带有与之关联的 customadapter 的 ListView。在这个 ListView 的布局中,我有另一个 ListView(也有它自己的 customadapter),其中只有 0 到 4 个项目。
外部/第一个列表视图中的行高需要根据内部/嵌套列表视图中的行数来扩展和收缩,但是这不会发生。它只会在留给自己的设备时显示一行。
我一直在随机分配带有layout_height:0
和layout_weight:1
的各种LinearLayouts 和ListViews,同时改变match_parent
与wrap_content
的值,但无济于事。
我知道这是一个简单的修复,但无法确定布局中的哪个元素需要哪些参数。我也不想以编程方式执行此操作。它应该只需要布局属性的正确组合。
提前致谢。
OUTER ListView 的布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_
android:layout_
>
<LinearLayout
android:layout_
android:layout_
android:padding="5dp">
<TextView
android:id="@+id/tvDate"
android:layout_
android:layout_ />
</LinearLayout>
<LinearLayout
android:layout_
android:layout_
android:orientation="vertical"
android:background="#ffdddd">
<LinearLayout
android:layout_
android:layout_
android:background="#ddffdd"
>
<ListView
android:id="@+id/lvInnerListView"
android:layout_
android:layout_
android:layout_weight="1"
/>
</LinearLayout>
<LinearLayout
android:layout_
android:layout_
android:background="#eeeeee">
<TextView
android:id="@+id/tvSomeOtherText"
android:layout_
android:layout_ />
</LinearLayout>
</LinearLayout>
</LinearLayout>
内部/嵌套列表视图的布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_
android:layout_
android:padding="5dp"
android:background="#ddddff">
<TextView
android:id="@+id/tvText1"
android:layout_
android:layout_ />
<TextView
android:id="@+id/tvText2"
android:layout_
android:layout_ />
<TextView
android:id="@+id/tvText3"
android:layout_
android:layout_ />
<TextView
android:id="@+id/tvText4"
android:layout_
android:layout_ />
<TextView
android:id="@+id/tvText5"
android:layout_
android:layout_ />
</LinearLayout>
片段本身的布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_
android:layout_>
<TextView
android:layout_
android:layout_
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Title" />
<Button
android:layout_
android:layout_
android:text="Get Values"
android:id="@+id/btnGetValues"
android:layout_marginTop="24dp"
android:layout_marginBottom="24dp"
android:padding="12dp"
android:textColor="#ffffff"/>
<TextView
android:layout_
android:layout_
android:text="Response from server"
android:id="@+id/tvResponse"/>
<LinearLayout
android:layout_
android:layout_>
<ListView
android:id="@+id/lvOuterListView"
android:layout_
android:layout_
android:layout_weight="1"
/>
</LinearLayout>
</LinearLayout>
【问题讨论】:
【参考方案1】:您面临的问题比简单调整参数更深。检查这个主题:How can I put a ListView into a ScrollView without it collapsing? - 它背后有解释。
首先也是最重要的,拥有可滚动视图内的嵌套可滚动视图(ListView
内的ListView
、RecyclerView
内的RecyclerView
、ScrollView
内的ScrollView
等)是a bad practice .
人们recommend 要做的是动态地向LinearLayout
动态添加和删除元素。 它会自动解决您的问题。 IE。 LinearLayout
将始终被“扩展”。
以下是实现它的方法(我将使用RecyclerView
而不是ListView
):
(是的,我知道没有设计看起来很糟糕,以代码为例)
你可以找到这个示例的源代码here;
在 Activity 中,我正在初始化“外部”RecyclerView
(实际上也是唯一的):
XML:
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/recyclerView"
android:layout_
android:layout_/>
代码:
RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(new CustomAdapter());
然后我创建一个CustomAdapter
:
public final class CustomAdapter extends RecyclerView.Adapter
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
return new CustomViewHolder(new CustomView(parent.getContext()));
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)
((CustomView)holder.itemView).bind(String.format("Position %s", position), position % 4);
@Override
public int getItemCount()
return 42;
class CustomViewHolder extends RecyclerView.ViewHolder
public CustomViewHolder(View itemView)
super(itemView);
下一步,为适配器创建CustomView
(在我的情况下,它将包含您的内部ListView
,只是一个LinearLayout
):
XML:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_
android:layout_>
<TextView
android:id="@+id/titleTextView"
android:layout_weight="1"
android:background="#F0F000"
android:layout_
android:layout_ />
<LinearLayout
android:id="@+id/containerLinearLayout"
android:layout_weight="1"
android:layout_
android:layout_
android:orientation="vertical"/>
</LinearLayout>
代码:
public final class CustomView extends FrameLayout
public CustomView(Context context)
super(context);
LayoutInflater.from(context).inflate(R.layout.view_item, this);
public void bind(String name, int value)
TextView textView = (TextView)getRootView().findViewById(R.id.titleTextView);
LinearLayout containerLinearLayout = (LinearLayout)getRootView().findViewById(R.id.containerLinearLayout);
textView.setText(name);
containerLinearLayout.removeAllViews();
for (int i = 0; i < value; i++)
containerLinearLayout.addView(new NestedCustomView(getContext()));
将条目添加到嵌套LinearLayout
(旧内部ListView
)的最后一步:
XML:
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:text="I'm a nested View"
android:background="#aa0a0a"
android:layout_
android:layout_
android:layout_marginBottom="8dp"/>
</merge>
代码:
public final class NestedCustomView extends FrameLayout
public NestedCustomView(Context context)
super(context);
LayoutInflater.from(context).inflate(R.layout.view_nested_item, this);
就是这样。同样,这个 HelloWorld 可用 here。
希望对你有帮助。
【讨论】:
谢谢。非常彻底的回答。我放入了您的代码部分并用您的适配器替换了我的适配器,它似乎工作得很好,显示类似于您的屏幕截图。现在,我将解构您的代码并尝试让我的自定义适配器与我的数据一起工作。感谢您在帖子/代码中所做的努力。 +1 康斯坦丁,在您的应用程序中,当您向下滚动列表时,应用程序的主窗口(标题“我的应用程序”)和状态栏是否也会移动?除了那个小问题之外,这对我来说非常有用,并且很高兴接受这个答案。谢谢 @Jammo 好吧,在这个 HelloWorld 中它保留在它原来的位置,但是你可以用CoordinatorLayout
& CollapsingToolbarLayout
折叠它或在它周围做一些动画(例如,像这样:@987654327 @)
康斯坦丁,是的,这里有同样的问题。 recyclerview(或containerLinearLayout
)似乎拉伸到比屏幕允许的更大的高度,这意味着整个页面(包括标题栏和寻呼机选项卡)也在滚动。如果我将视图限制为 100dp,那么这将停止发生。它似乎扩展了与寻呼机选项卡相同的高度,这意味着view
可能正在查看最上面的视图进行计算,而不仅仅是其父视图?不太确定
@Jammo 你用 LinearLayout 替换了内部 ListView 吗?以上是关于嵌套的 ListViews 没有扩展到全高的主要内容,如果未能解决你的问题,请参考以下文章
Flex React Native FlatList 孩子长到全高?