adapter - Android布局——listview会根据数据数量自动调节高度吗
阿神
阿神 2017-04-17 13:30:38
0
2
360

最近在看一个项目的源码,有一个实现listview里嵌套listview的功能,实现方式是用Adapter嵌套Adapter。但是在主Adapter里,有一个函数用于更改子listview的布局高度。

public static 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 = totalHeight
                + (listView.getpiderHeight() * (listAdapter.getCount() - 1));
        listView.setLayoutParams(params);
    }

显然这个函数会根据adapter中数据的个数调节listview布局的高度,那么为什么listview不会自己调节呢?

阿神
阿神

闭关修行中......

全部回覆(2)
大家讲道理

因為巢狀的ListView不需要也不應該可以捲動

所以在程式碼中 需要將嵌套的ListView調整到剛好能顯示所有Child的高度

而對於ListView本身而言,它是不關心自身高度和是否能顯示下所有Child的,因為就原始設計上而言,它是一個可以滾動的組件.


你也可以自己閱讀下面這段程式碼來看看ListView的measure自身高度的邏輯
看看MeasureSpec.UNSPECIFIED模式下ListView的高度是怎麼來的

 @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // Sets up mListPadding
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        int childWidth = 0;
        int childHeight = 0;
        int childState = 0;

        mItemCount = mAdapter == null ? 0 : mAdapter.getCount();
        if (mItemCount > 0 && (widthMode == MeasureSpec.UNSPECIFIED ||
                heightMode == MeasureSpec.UNSPECIFIED)) {
            final View child = obtainView(0, mIsScrap);

            measureScrapChild(child, 0, widthMeasureSpec);

            childWidth = child.getMeasuredWidth();
            childHeight = child.getMeasuredHeight();
            childState = combineMeasuredStates(childState, child.getMeasuredState());

            if (recycleOnMeasure() && mRecycler.shouldRecycleViewType(
                    ((LayoutParams) child.getLayoutParams()).viewType)) {
                mRecycler.addScrapView(child, 0);
            }
        }

        if (widthMode == MeasureSpec.UNSPECIFIED) {
            widthSize = mListPadding.left + mListPadding.right + childWidth +
                    getVerticalScrollbarWidth();
        } else {
            widthSize |= (childState&MEASURED_STATE_MASK);
        }

        if (heightMode == MeasureSpec.UNSPECIFIED) {
            heightSize = mListPadding.top + mListPadding.bottom + childHeight +
                    getVerticalFadingEdgeLength() * 2;
        }

        if (heightMode == MeasureSpec.AT_MOST) {
            // TODO: after first layout we should maybe start at the first visible position, not 0
            heightSize = measureHeightOfChildren(widthMeasureSpec, 0, NO_POSITION, heightSize, -1);
        }

        setMeasuredDimension(widthSize , heightSize);
        mWidthMeasureSpec = widthMeasureSpec;        
    }
迷茫

因為ListView要重複使用ConvertView

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板