问题:
ScrollView与ListView共存时,ListView会只显示一行,其它行无法显示。
解决方案:
重写ListView如下即可解决问题。
/**解决ScorllView与ListView共存时,ListView只显示一行、不能完全显示的问题。
* @author Caiyuan Huang
* 2014-9-26
*/
public class CustomListView extends ListView {
public CustomListView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public CustomListView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public CustomListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}
虽然上述方案能够解决ListView的显示问题,但是还有一个很致命的问题也许很多人都没有发现,那就是ListView的adapter的getView方法会被重复调用多次,有时甚至是10次之多,严重影响性能,当异步加载图片的时候,卡的你喊爹娘。解决方案就是不让ListView与ScrollView共存,取而代之的是用ViewGroup去不断的添加Item。
一下是解决方案之一,请参考。
/**
* 解决与ScrollView共存时导致的两个问题:
* <p>
* 1、ListView只显示一行。
* </p>
* <p>
* 2、ListView的adapter的getView会被重复调用多遍。
* </p>
*
* @author Caiyuan Huang
* <p>
* 2014-9-29
* </p>
*/
public class CustomListView2 extends LinearLayout {
private BaseAdapter adapter = null;
private int defaultDividerId = -9999;
private int dividerDrawableId = defaultDividerId;
/**
* 上一次的孩子个数,依据此判断是全部清除child,还是在后面追加child
*/
private int preChildCount = 0;
private OnItemClickListener mOnItemClickListener = null;
public CustomListView2(Context context) {
super(context);
setOrientation(VERTICAL);
}
public CustomListView2(Context context, AttributeSet attrs) {
super(context, attrs);
setOrientation(VERTICAL);
}
/**
* 设置分割线id
*
* @param id
*/
public void setDividerDrawableId(int id) {
this.dividerDrawableId = id;
}
/**
* 当数据改变时刷新界面
*
*/
public void notifyDataSetChanged() {
if (adapter == null) {
throw new RuntimeException("请先调用setAdapter方法,设置适配器!");
}
if (preChildCount >= adapter.getCount())
this.removeAllViews();
int count = dividerDrawableId == defaultDividerId ? getChildCount()
: getChildCount() / 2;
LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT);
for (int i = count; i < adapter.getCount(); i++) {
final int childIndex = i;
View v = adapter.getView(i, null, this);
v.setLayoutParams(params);
addView(v, childIndex);
if (mOnItemClickListener != null)
v.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (mOnItemClickListener != null)
mOnItemClickListener.onItemClick(null, v,
childIndex, (long) v.getId());
}
});
if (dividerDrawableId == defaultDividerId)
continue;
// 设置listview的分割线
ImageView imgDivider = new ImageView(getContext());
imgDivider.setBackgroundResource(dividerDrawableId);
imgDivider.setLayoutParams(params);
addView(imgDivider, childIndex + 1);
}
preChildCount = dividerDrawableId == defaultDividerId ? getChildCount()
: getChildCount() / 2;
}
/**
* 获取适配器
*
* @return
*/
public BaseAdapter getAdapter() {
return adapter;
}
/**
* 设置适配器
*
* @param adpater
*/
public void setAdapter(BaseAdapter adpater) {
this.adapter = adpater;
notifyDataSetChanged();
}
/**
* 设置条目点击监听,不要在OnItemClick里面获取 parent,因为其为null。
*
* @param listener
*/
public void setOnItemClickListener(OnItemClickListener listener) {
this.mOnItemClickListener = listener;
}
}