一个样式引发的血案。。。。。
在ListView中加载图片,用到了BaseAdapter,重写了getView();我的神啊,显示的数据没有几个,但是这个方法被调用了N多次,
这个慢啊。。。。百思不得“其姐”啊;我以为我的代码写的有问题,从网上找了好多代码看,发现没有问题。。。结果是个样式,终于
知道那些发代码的人为什么要粘xml啦。。。
1、xml si_page
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#fcfcfc"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:background="@drawable/search_bar_bg" >
<EditText
android:id="@+id/editText1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="搜索"
android:singleLine="true"
android:focusable="true"
android:focusableInTouchMode="true"
android:textColor="#000"
android:drawableLeft="@drawable/search_bar_icon_normal"
android:background="@drawable/search_bar_edit_bg" >
</EditText>
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:background="@drawable/mm_listitem"
android:clickable="true"
android:onClick="startchat"
>
<ListView
android:id="@+id/viewSIList"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:cacheColorHint="#00000000"
android:divider="@drawable/list_line"
android:fadingEdge="none"
android:listSelector="#00000000"
android:scrollbarThumbVertical="@drawable/scrollbar"
android:background="@color/silist">"
</ListView>
</RelativeLayout>
</LinearLayout>
注意红色字!这个地方必须这么写;只要不这么写,getView()会调用好多次(跟你加载的数据数量有关);
“因为ListView设置成了Wrap,所以要计算每个Item的高度,然后再反过来改变ListView的高度,这时候ListView的高度变更了,会触发ListView的invalidate()函数,又要重新绘制。所以getView同一个position会调用多次”引用别人的解释
XML si_item_page
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="80.0dip"
android:background="#fcfcfc"
android:drawingCacheQuality="high"
android:minHeight="70.0dip"
android:orientation="horizontal" >
<!-- 头像 -->//注意这里不要设置背景图片,会出现两个图片重叠
<ImageView
android:id="@+id/sItemIcon"
android:layout_width="64.0dip"
android:layout_height="64.0dip"
android:layout_margin="10.0dip"
android:padding="2.0dip"
android:scaleType="fitXY" />
<!-- 姓名 -->
<TextView
android:text="黄山"
android:id="@+id/sItemName"
android:layout_width="100dip"
android:layout_height="30.0dip"
android:layout_alignTop="@+id/sItemIcon"
android:layout_toRightOf="@+id/sItemIcon"
android:gravity="center_vertical"
android:singleLine="true"
android:textColor="@color/listTitle"
android:textSize="18.0sp" />
</RelativeLayout>
2、Adapter
package com.fengsidai.si;
import 。。。。
public class SIItemAdapter extends BaseAdapter implements OnScrollListener{
private LayoutInflater mInflater;
private Context mContext;
public Vector<SIModel> mModels;
private ListView mListView;
public SIItemAdapter(Context context,Vector<SIModel> models){
mContext=context;
mInflater = LayoutInflater.from(mContext);//-------------------------------------
mModels=models;
}
public void clean(){
mModels.clear();
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return mModels.size();
}
@Override
public Object getItem(int position) {
if(position >= getCount()){
return null;
}
return mModels.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
private class ViewHolder {
ImageView iv;
TextView siName;
TextView siIntimacy;
TextView sillcName;
TextView siIndustry;
TextView siSource;
TextView siResources;
}
//@Override
public View getView(int position, View convertView, ViewGroup parent) {
System.out.println("getView " + position + " " + convertView);//调试语句
// 常见的优化ViewHolder
ViewHolder viewHolder = null;
if (null == convertView) {
convertView = mInflater.inflate(R.layout.si_item_adapter, null);
viewHolder = new ViewHolder();
viewHolder.iv = (ImageView) convertView.findViewById(R.id.sItemIcon);
viewHolder.siName = (TextView) convertView.findViewById(R.id.sItemName);
viewHolder.siIntimacy = (TextView) convertView.findViewById(R.id.sItemIntimacy);
viewHolder.sillcName = (TextView) convertView.findViewById(R.id.sItemllcName);
viewHolder.siIndustry = (TextView) convertView.findViewById(R.id.sItemIndustry);
viewHolder.siSource = (TextView) convertView.findViewById(R.id.sItemSource);
viewHolder.siResources = (TextView) convertView.findViewById(R.id.sItemResources);
convertView.setTag(viewHolder);
}else{
viewHolder = (ViewHolder) convertView.getTag();
}
//-------------------------------------加载数据
SIModel model = (SIModel)getItem(position);
viewHolder.siName.setText(model.getName());
viewHolder.siIntimacy.setText(model.getIntimacy());
viewHolder.sillcName.setText(model.getLlcName());
viewHolder.siIndustry.setText(model.getIndustry());
viewHolder.siSource.setText(model.getSource());
viewHolder.siResources.setText(model.getResources());
System.out.println("position:"+position);
System.out.println("siName:"+model.getName());
System.out.println("PICURL:"+model.getPicUrl());
Drawable d=loadImageFromUrl(model.getPicUrl());
viewHolder.iv.setImageDrawable(d);
return convertView;
}
private Drawable loadImageFromUrl(String picname) {
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
File f = new File(Environment.getExternalStorageDirectory()+"/ViperLb/"+picname);
if(f.exists()){
FileInputStream fis;
Drawable d;
try {
fis = new FileInputStream(f);
d= Drawable.createFromStream(fis, "src");
return d;
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}else{//不存在
return null;
}
}else{//sd卡不正常
return null;
}
}
@Override
public void onScroll(AbsListView arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
}
@Override
public void onScrollStateChanged(AbsListView arg0, int arg1) {
// TODO Auto-generated method stub
}
}
注释:
android SDK中这样讲参数 convertview :
the old view to reuse, if possible. Note: You should check that this view is non-null and of an appropriate type before using.
If it is not possible to convert this view to display the correct data, this method can create a new view.
翻译:
如果可以的话,这是旧View(这里不便翻译有的人翻成视图)的重用。 建议:在用之前,你应该检查这个View是
不是非空,是不是一个合适的类型。
如果不可能让这个VIew去显示一个恰当的数据,这个方法会创建一个新的View。
上面调试语句输出中,convertView显示为NULL,是第一次加载,不为空就不是第一次加载,样式会导致这个问题!
3、Activity 中一个方法调用Adapter
ListView viewSIList;//
SIItemAdapter SIadapter;//处理list的类
private Vector<SIModel> mModels;//实体
private void Binding_si_list(){
viewSIList=(ListView)findViewById(R.id.viewSIList);
mModels=new Vector<SIModel>();
List_si_select=dbhelper.SeclectTable(sqldb);
for(int i=0;i<List_si_select.size();i++){
sId=Integer.parseInt(List_si_select.get(i).get("sId").toString());
sName=List_si_select.get(i).get("sName").toString();
//System.out.println("view:"+sName);
sIntimacy=List_si_select.get(i).get("sIntimacy").toString();
sSource=List_si_select.get(i).get("sSource").toString();
sLlcName=List_si_select.get(i).get("sLlcName").toString();
sIndustry=List_si_select.get(i).get("sIndustry").toString();
sResources=List_si_select.get(i).get("sResources").toString();
sPicName=List_si_select.get(i).get("sPicName").toString();
SIModel simodel=new SIModel();
simodel.SetModel(sName, sLlcName, sIntimacy, sSource, sIndustry, sPicName, sResources);
mModels.add(simodel);
}
SIadapter=new SIItemAdapter(this,mModels);
viewSIList.setAdapter(SIadapter);//数据 添加到 listview
}