Android ExpandableListView和ScrollView联用的一些注意事项

之前有整理过ScrollView嵌套ListView的例子,讲的是计算listview的每一项的高度。已达到目标效果。同样的ExpandableListView嵌套ScrollView也是这么个思路,不过要稍微加一些方法和稍微做一些改动。

要实现这个功能首先要准备三个基础的方法:

一、计算ExpandableListView的group项的高度的方法(即计算listview合并时的高度的方法)备注:ExpandableListView是listview的子类所以,listview的方法它同样可以使用

/** 动态改变listView的高度 */
    public void setListViewHeightBasedOnChildren(ListView listView) {
        ListAdapter listAdapter = listView.getAdapter();
        if (listAdapter == null) {
            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 = 80 * (listAdapter.getCount() - 1);
        // params.height = 80 * (listAdapter.getCount());
        params.height = totalHeight
                + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
        ((MarginLayoutParams) params).setMargins(0, 0, 0, 0);
        listView.setLayoutParams(params);

    }

二、计算ExpandableListView展开时group下的子view列表的高度的方法

/**
     * 可扩展listview展开时调用
     * 
     * @param listView
     * @param groupPosition
     */
    public static void setExpandedListViewHeightBasedOnChildren(
            ExpandableListView listView, int groupPosition) {
        ExpandableListAdapter listAdapter = listView.getExpandableListAdapter();
        if (listAdapter == null) {
            return;
        }
        View listItem = listAdapter.getChildView(groupPosition, 0, true, null,
                listView);
        listItem.measure(0, 0);
        int appendHeight = 0;
        for (int i = 0; i < listAdapter.getChildrenCount(groupPosition); i++) {
            appendHeight += listItem.getMeasuredHeight();
        }
        ViewGroup.LayoutParams params = listView.getLayoutParams();
//        Log.d(TAG, "Expand params.height" + params.height);
        params.height += appendHeight;
        listView.setLayoutParams(params);
    }

三、计算ExpandableListView合并时消除group下的子view列表的高度的方法

/**
     * 可扩展listview收起时调用
     * 
     * @param listView
     * @param groupPosition
     */
    public static void setCollapseListViewHeightBasedOnChildren(
            ExpandableListView listView, int groupPosition) {
        ExpandableListAdapter listAdapter = listView.getExpandableListAdapter();
        if (listAdapter == null) {
            return;
        }
        View listItem = listAdapter.getChildView(groupPosition, 0, true, null,
                listView);
        listItem.measure(0, 0);
        int appendHeight = 0;
        for (int i = 0; i < listAdapter.getChildrenCount(groupPosition); i++) {
            appendHeight += listItem.getMeasuredHeight();
        }
        /*Log.d(TAG,
                "Collapse childCount="
                        + listAdapter.getChildrenCount(groupPosition));*/
        ViewGroup.LayoutParams params = listView.getLayoutParams();
        params.height -= appendHeight;
        listView.setLayoutParams(params);
    }

三个计算方法都贴出来了,下面来看看这三个方法到底是怎样使用的

一、在设置ExpandableListView的adapter的时候计算一下它合并时的宽度,并显示出来。(这一步是初始化)

例如:

listView.setAdapter(adapter);
ListUtil.getInstance().setListViewHeightBasedOnChildren(listView);

二、当ExpandableListView展开时调用计算方法

例如:

/**
         * 当ExpandableListView展开时调用
         */
        listView.setOnGroupExpandListener(new OnGroupExpandListener() {

            @Override
            public void onGroupExpand(int groupPosition) {
                /*
                 * Log.e("expand", "扩展"); for (int i = 0; i < 4; i++) { if
                 * ((groupPosition != i) && listView.isGroupExpanded(i)) {
                 * listView.collapseGroup(i); } }
                 */
                /**
                 * 计算group下的子项的高度
                 */
                ListUtil.setExpandedListViewHeightBasedOnChildren(listView,
                        groupPosition);
                // 更新group每一项的高度
                ListUtil.getInstance().setListViewHeightBasedOnChildren(
                        listView);
            }
        });

三、当ExpandableListView合并时调用计算方法

例如:

/**
         * 当ExpandableListview收缩时调用
         */
        listView.setOnGroupCollapseListener(new OnGroupCollapseListener() {

            @Override
            public void onGroupCollapse(int groupPosition) {
                Log.e("collapse", "收缩");

                /*
                 * 计算group下的每一个子项的高度,然后收缩
                 */
                ListUtil.setCollapseListViewHeightBasedOnChildren(listView,
                        groupPosition);
                /*
                 * 重新评估group的高度
                 */
                ListUtil.getInstance().setListViewHeightBasedOnChildren(
                        listView);
                /*
                 * ListUtil.setCollapseListViewHeightBasedOnChildren(listView,
                 * groupPosition);
                 */
            }
        });

好了,到这里就结束了。备注:在计算方发中的adapter中的layout外层布局不能是RelativeLayout,否则将会报空指针。具体什么原因我就不说了,晚上一大堆的。

原文地址:https://www.cnblogs.com/tony-yang-flutter/p/3842979.html