这种情况是当ScrollView嵌套ListView时,ListView的高度设置为wrap_content时会产生,一般情况下ListView只显示的第一个Item。
正常情况下,高度设置为“wrap_content”的ListView在测量自己的高度会使用MeasureSpec.AT_MOST这个模式高度来返回可包含住其内容的高度。
而实际上当ListView被ScrollView嵌套时,ListView使用的测量模式是ScrollView传入的MeasureSpec.UNSPECIFIED。
解决方法一:重写ListView的onMeasure方法:
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.widget.ListView;
public class MyListView extends ListView {
public MyListView(Context context) {
super(context);
}
public MyListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public MyListView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int newHeightMeasureSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE>>2, // 设计一个较大的值和AT_MOST模式
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, newHeightMeasureSpec);//再调用原方法测量
}
}
解决方法二:在Activity中动态修改ListView的高度,注意当ListView的子item需要根布局是LinearLayout,或需要为一个View,因为有些布局中没有measure这个方法,比如RelativeLayout。
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); // 获取item高度
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
// 最后再加上分割线的高度和padding高度,否则显示不完整。
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1))+listView.getPaddingTop()+listView.getPaddingBottom();
listView.setLayoutParams(params);
}
调用这个方法,把listview传进去就可以解决了。
网友评论