9.解决ScrollView与ListView共存时ListView高度无法完全显示的问题。

来源:互联网 发布:相貌评分软件结果 编辑:程序博客网 时间:2024/05/17 06:52

问题:

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;
}
}

0 0