我用推荐的模式编写了一个自定义的listview数组适配器,该模式指示我们应该在getView()方法内使用ViewHolder以获得性能(和电池)。我遇到麻烦的地方是应该在复选框组件中添加侦听器。在我的listview适配器源文件之后,我将更加明确:
package com.loloof64.android.chess_position_manager.file_explorer;
// all my importes (eluded)
public class FilesListArrayAdapter extends ArrayAdapter<ListFileElement> {
private final Context context;
private final ArrayList<ListFileElement> elements;
private final ArrayList<ListFileElement> selectedElements = new ArrayList<>();
private boolean isSelectionMode = false;
public FilesListArrayAdapter(Context context, ListFileElement[] objects) {
super(context, R.layout.file_list_view, objects);
this.context = context;
this.elements = new ArrayList<>(Arrays.asList(objects));
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
// reuse views
if (rowView == null){
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflater.inflate(file_list_view, parent, false);
// configure view holder
FileItemViewHolder viewHolder = new FileItemViewHolder();
viewHolder.checkBoxView = (CheckBox) rowView.findViewById(R.id.file_list_item_checkbox);
viewHolder.nameView = (TextView) rowView.findViewById(R.id.file_list_item_name);
viewHolder.iconView = (ImageView) rowView.findViewById(R.id.file_list_item_icon);
// **** 1 *****
// Should I add item listeners here ?
rowView.setTag(viewHolder);
}
// fill data
FileItemViewHolder viewHolder = (FileItemViewHolder) rowView.getTag();
ListFileElement bindedElement = elements.get(position);
viewHolder.nameView.setText(bindedElement.getFileName());
// **** 2 *****
// Should I rather add item listeners here ?
viewHolder.checkBoxView.setVisibility(isSelectionMode ? View.VISIBLE : View.GONE);
viewHolder.checkBoxView.setClickable(ListFileElement.PARENT_DIR != bindedElement);
if (bindedElement.isDirectory()){
viewHolder.iconView.setImageResource(R.drawable.ic_folder);
}
else {
viewHolder.iconView.setImageResource(R.drawable.ic_file);
}
return rowView;
}
public boolean isSelectionMode() {
return isSelectionMode;
}
public void toggleSelectionMode(){
isSelectionMode = !isSelectionMode;
}
public ListFileElement[] getSelectedElements(){
return selectedElements.toArray(new ListFileElement[0]);
}
}
当然,不需要ListFileElement源代码即可了解我的问题。您应该已经在我的源文件的代码注释中注意到**** 1 *****和**** 2 ****部分。
使我麻烦的是,项目加载效率和编程正确性(无错误):在ViewHolder(第1节)中添加控件或在每次加载项目视图(第2节)之后添加控件时,我应该添加项目复选框侦听器吗?
创建行时,您可以设置一次侦听器。但是,一旦需要设置它们,就需要某种方式(在侦听器内部)知道单击了什么。为此,您必须在绑定视图时指定该行所属的元素。与此类似的东西应该起作用:
// reuse views
if (rowView == null){
...
// **** 1 *****
viewHolder.checkboxView.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Checkbox cb = (Checkbox) v;
int position = (Integer)v.getTag();
ListFileElement bindedElement = getItem(position);
if (cb.isChecked()) {
// Do something
} else {
// Do something else
}
}
});
rowView.setTag(viewHolder);
}
// Bind the view
viewHolder.checkboxView.setTag(position);
由于绑定视图时将项目的位置设置为复选框上的标签,因此复选框单击侦听器可以简单地从复选框标签中获取该位置并获取对该项目的引用。
另外,您可以简单地将项目设置为标签,而不是位置参考!
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句