我在android中为ListView
创建了一个适配器,它的行为非常奇怪。列表视图传递一个对象列表,按一些规则排序(比较数字,哇......)。现在,当视图中显示列表时,会显示重复条目,它们不会被排序,条目丢失,当我滚动列表时,即使条目更改!发生了什么事?
以下是适配器的代码,如果有必要,我可以发布更多代码:
public class StatViewAdapter extends BaseAdapter {
Activity activity;
ArrayList<Entry> entries;
TextView txtName;
TextView txtOK;
TextView txtNOK;
TextView txtHist;
TextView txtPrandom;
TextView txtPhist;
TextView txtPtotal;
//public StatViewAdapter(Activity activity, ArrayList<HashMap<String, String>> list){
public StatViewAdapter(Activity activity, ArrayList<Entry> entries){
super();
this.activity=activity;
this.entries = entries;
Collections.sort(this.entries, new Comparator<Entry>() {
@Override
public int compare(Entry o1, Entry o2) {
if (o1.getPriority() > o2.getPriority()) {
return 1;
}
if (o1.getPriority() < o2.getPriority()) {
return -1;
}
return 0;
}
});
for (int i=0;i<this.entries.size();i++) {
String name = this.entries.get(i).name();
int p = this.entries.get(i).getPriority();
System.out.println(String.format("%s: %d", name, p));
}
}
@Override
public int getCount() {
// TODO Auto-generated method stub
//return list.size();
return this.entries.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return this.entries.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
LayoutInflater inflater=this.activity.getLayoutInflater();
if(convertView == null){
convertView=inflater.inflate(R.layout.list_view, null);
txtName=(TextView) convertView.findViewById(R.id.listname);
txtOK=(TextView) convertView.findViewById(R.id.listok);
txtNOK=(TextView) convertView.findViewById(R.id.listnok);
txtHist=(TextView) convertView.findViewById(R.id.listhist);
txtPrandom =(TextView) convertView.findViewById(R.id.listprandom);
txtPhist=(TextView) convertView.findViewById(R.id.listphist);
txtPtotal=(TextView) convertView.findViewById(R.id.listptot);
}
Entry entry = this.entries.get(position);
txtName.setText(entry.name());
txtOK.setText(Integer.toString(entry.number_ok));
txtNOK.setText(Integer.toString(entry.number_nok));
txtHist.setText(entry.history);
txtPrandom.setText(Integer.toString(entry.randomIndex));
txtPhist.setText(Integer.toString(entry.histIndex));
txtPtotal.setText(Integer.toString(entry.getPriority()));
return convertView;
}
}
答案 0 :(得分:2)
public View getView(int position, View convertView, ViewGroup parent)
的目的是将给定position
处对象的数据绑定到视图。视图可能是循环视图(convertView
),或者您需要在方法中创建一个视图。问题是您不应该在txtName
中保留对这些视图的引用(txtOk
,Adapter
)。
public class StatViewAdapter extends BaseAdapter {
Activity activity;
ArrayList<Entry> entries;
//TextView txtName;
//TextView txtOK;
// ...
public StatViewAdapter(Activity activity, ArrayList<Entry> entries){
// ...
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater=this.activity.getLayoutInflater();
if(convertView == null){
convertView=inflater.inflate(R.layout.list_view, null);
}
TextView txtName=(TextView) convertView.findViewById(R.id.listname);
TextView txtOK=(TextView) convertView.findViewById(R.id.listok);
// ...
Entry entry = this.entries.get(position);
txtName.setText(entry.name());
txtOK.setText(Integer.toString(entry.number_ok));
// ....
return convertView;
}
它有效,但它仍然不是一个好方法,你可能想要使用RecyclerView
或实现ViewHolder
模式。
ViewHolder
模式的想法是,每次绑定视图时都不必调用findViewById
,因为它的计算成本很高并且可能导致滚动滞后。
您可能希望使用RecyclerView
,因为它是一个更新,更灵活的视图,可以执行ListView
相同的工作,并且内置ViewHolder
模式