ScrollView里面嵌套ListView默认情况下会导致ListView的高度只有一个条目高度,即无论怎样滚动,始终只显示一个条目(不管布局中ListView高度是wrap_content还是match_parent)
网上的解决方案有一种是重写ListView的onMeasure 方法实现,
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
虽然这种方法确实能达到效果但却导致ListView中子控件不能重用,而且只要一设置adapter就会调用 若干次getView方法(adapter.getCount*n 次),并且所有的子控件都是新创建的,而不是复用的,同时会导致滚动listview时不再调用getView方法
下图中 滚动时并没有调用getView方法
为了解决上述所有问题,只需要在java代码中设置ListView布局参数即可解决(布局参数中指定ListView高度)
如 :
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listview=(ListView) findViewById(R.id.listview);
LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 400);
listview.setLayoutParams(params);
listview.setAdapter(new MyAdapter());
}
这里我们指定ListView高度是400,实际使用中需根据具体情况修改这个值
下面是在320*480模拟器上的效果,可以看到ListView正确显示 了,而且子控件是复用的,滚动时会调用getView方法
附相关代码
Adapter
class MyAdapter extends BaseAdapter{
@Override
public int getCount() {
return 15;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Log.v("getView", position+" view= "+ convertView);
if (convertView==null) {
ViewGroup v=(ViewGroup) LayoutInflater.from(getApplicationContext()).inflate(R.layout.item , listview,false);
((TextView)v.getChildAt(1)).setText("null.."+position);
return v;
}
ViewGroup v=(ViewGroup)convertView;
((TextView)v.getChildAt(1)).setText(""+position);
return convertView;
}
}
Item布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="#e1e1e1"
android:padding="10dp"
android:gravity="center_vertical">
<ImageView
android:layout_width="60dp"
android:layout_height="60dp"
android:src="@drawable/ic_launcher"/>
<TextView android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="xxx"
android:textColor="#000"/>
</LinearLayout>
Activity布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.measurelistview.MainActivity" >
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_world" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.example.measurelistview.MeasureListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
</com.example.measurelistview.MeasureListView>
</LinearLayout>
</ScrollView>
</RelativeLayout>
MeasureListView
package com.example.measurelistview;
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ListView;
public class MeasureListView extends ListView {
public MeasureListView(Context context) {
super(context);
}
public MeasureListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MeasureListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@SuppressLint("NewApi")
public MeasureListView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
// @Override
// protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//
// int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST);
//
// super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//
// }
}