Android list view inside a scroll view

后端 未结 30 2131
一向
一向 2020-11-21 13:43

I have an android layout which has a scrollView with a number of elements with in it. At the bottom of the scrollView I have a listView

30条回答
  •  春和景丽
    2020-11-21 13:43

    Ok, here 's my answer. The method that fixes the ListView height is closed enough, but not perfect. In case that most of the items are the same height, that work well. But in case that's not, then there's a big problem. I've tried many time, and when I put out the value of listItem.getMeasureHeight and listItem.getMeasuerWidth into the log, I saw the width values vary a lot, which is not expected here, since all the item in the same ListView should have the same width. And there go the bug :

    Some used measure(0 ,0), which actually made the view unbound, in both direction, and width run wild. Some tried to getWidth of listView, but then it return 0, meaningless.

    When I read further into how android render the View, I realize that all of this attempt can't reach the answer that I searched for, unless these function run after the view is render.

    This time I use the getViewTreeObserver on the ListView that I want to fix height, then addOnGlobalLayoutListener. Inside this method, I declare a new OnGlobalLayoutListener, in which, this time, getWidth return the actual width of the ListView.

    private void getLayoutWidth(final ListView lv, final int pad){
            //final ArrayList width = new ArrayList();
    
            ViewTreeObserver vto = lv.getViewTreeObserver();
            vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    lv.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                    //width.add(layout.getMeasuredWidth());
                    int width = lv.getMeasuredWidth();
                    ListUtils.setDynamicHeight(lv, width, pad);
                }
            });
        }
    
    public static class ListUtils {
            //private static final int UNBOUNDED = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
            public static void setDynamicHeight(ListView mListView, int width, int pad) {
                ListAdapter mListAdapter = mListView.getAdapter();
                mListView.getParent();
                if (mListAdapter == null) {
                    // when adapter is null
                    return;
                }
                int height = 0;
    
    
                int desiredWidth = View.MeasureSpec.makeMeasureSpec(width - 2*pad, View.MeasureSpec.EXACTLY);
                for (int i = 0; i < mListAdapter.getCount(); i++) {
                    View listItem = mListAdapter.getView(i, null, mListView);
    
                    listItem.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
                    //listItem.measure(UNBOUNDED, UNBOUNDED);
                    height += listItem.getMeasuredHeight() + 2*pad;
                    Log.v("ViewHeight :", mListAdapter.getClass().toString() + " " + listItem.getMeasuredHeight() + "--" + listItem.getMeasuredWidth());
                }
                ViewGroup.LayoutParams params = mListView.getLayoutParams();
                params.height = height + (mListView.getDividerHeight() * (mListAdapter.getCount() - 1));
                mListView.setLayoutParams(params);
                mListView.requestLayout();
            }
        }
    

    The value pad, is the padding that I set in ListView layout.

提交回复
热议问题