天天看点

ScrollView+ListView冲突问题解决

问题1:ScrollView+ListView时,listView内容只显示一行:

解决:使用setListViewHeightBaseOnChildren,具体代码如下:

private void setListViewHeightBaseOnChildren(ListView listView) {
        ListAdapter listAdapter = listView.getAdapter();
        if (listAdapter == null) {
            // pre-condition
            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.getDividerHeight() * (listAdapter.getCount() - 1));
        listView.setLayoutParams(params);
    }
           

需要注意的一点是,此函数的调用时机。需要在给listview设置完adapter且adapter内容显示完毕之后再调用有效。

若是在刚定义listview时调用,因为此时listview是空的,无任何内容,调用后仍然显示一行。因此,简单来说,就是要在给listview的adapter添加完数据后显示时调用此函数;还有一种就是重写listView,在使用listView时使用自定义的即可,重写代码如下:

public class ListViewForScrollView extends ListView {
    public ListViewForScrollView(Context context) {
        super(context);
    }

    public ListViewForScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ListViewForScrollView(Context context, AttributeSet attrs,
        int defStyle) {
        super(context, attrs, defStyle);
    }
        
    @Override
    /**
     * 重写该方法,达到使ListView适应ScrollView的效果
     */
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
                MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);
    }
}
           

问题2、进入ScrollView+listView界面时,不在界面顶部,显示界面中间的问题:

原因:listview自动获取了焦点;

解决:listView.setFocusable(false);这个只要放在listview定义的地方即可。

继续阅读