【问题标题】:Is it possible to have a listView of items in the header of an expandableListView是否可以在可扩展列表视图的标题中包含项目的列表视图
【发布时间】:2014-04-29 01:07:03
【问题描述】:

基本上,我需要一些通过适配器动态可用的内容来填充我的 expandableListView 的标题,这一定是可能的,但是很难找到有关此问题的任何资源。

这是我想要做的事情的代表。

【问题讨论】:

  • 不容易,在我自己尝试之后,在标题中使用LinearLayout 而不是ListView 要好得多/更容易。
  • 其实我很久以前就解决了这个问题,应该已经更新了,你最好的办法是使用一个 ListView 填充你知道大小的项目。然后获取每个高度的 X 次,并以编程方式将该高度设置为 ListView,使其不会滚动。

标签: android xml android-listview expandablelistview


【解决方案1】:

是的,但您需要覆盖 onGlobalLayout(),并在标题中设置 listView 的高度,例如

final ExpandableListView lExpView = (ExpandableListView) view.findViewById(R.id.expandable_list);

View viewHdr = getActivity().getLayoutInflater().inflate(R.layout.pager_header, lExpView, false);
final ListView lView = (ListView) viewHdr.findViewById(R.id.item_hdr_list);

...

lView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @SuppressLint("NewApi")
    @SuppressWarnings("deprecation")
    @Override
    public void onGlobalLayout() {
        if (lView.getVisibility() == View.VISIBLE) adjustTotalHeightOfListView(lView, lExpView);
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN)
                lExpView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            else
                lExpView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
        }
    });

adjustTotalHeightOfListView() 是您自己设计的一种方法,可以计算和设置列表视图的高度,同时包含在可扩展列表视图的标题中。如果 listView 中的单个项目的高度可以超过一个文本行(比可扩展列表视图的宽度宽并且您设置了 WRAP_CONTENT),那么这会有点复杂,因为包含的实际宽度ExpandableListView 在渲染之前将不可用,但我们至少需要先猜测一下才能让这种情况发生。所以你会想要一些看起来有点像(未经测试)的代码:

if (listView == null) return;
ListAdapter mAdapter = listView.getAdapter();
if (mAdapter == null) return;
int totalHeight = listView.getPaddingBottom() + listView.getPaddingTop();
int viewWidth = ( parent == null || parent.getWidth() <= 0 )
            ? listView.getWidth()
            : parent.getWidth();

....

for (int i = 0; i < mAdapter.getCount(); i++) {
    View mView = mAdapter.getView(i, null, listView);

    mView.measure(
            View.MeasureSpec.makeMeasureSpec(viewWidth, (viewWidth > 0) 
                ? View.MeasureSpec.AT_MOST 
                : View.MeasureSpec.UNSPECIFIED
            ),
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
    );
    totalHeight += mView.getMeasuredHeight() + listView.getDividerHeight();
}

....

ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight;
listView.setLayoutParams(params);
listView.requestLayout();

注意:? View.MeasureSpec.AT_MOST : View.MeasureSpec.UNSPECIFIED hack 在 measure() 语句中,本质上它是为了应对在父视图展开/有一个之前进行的调用宽度设置。如果设置了宽度,则不要超过它,因此如果指定了 WRAP_CONTENT 并且宽度大于父级,则将调整高度,否则假设您可以与内容一样宽。

其中:pager_header.xml

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

<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:orientation="vertical"
      android:gravity="center">

    <ListView
        android:id="@+id/item_hdr_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal" />

</GridLayout>

主布局包含:

<?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="match_parent"
      android:orientation="vertical"
      android:gravity="center">

    <ExpandableListView
        android:id="@+id/expandable_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center_horizontal"
        android:paddingBottom="10dp" />

</LinearLayout>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 2017-07-17
    • 2016-07-16
    • 2012-03-28
    相关资源
    最近更新 更多