2014-12-21 1 views
0

Я написал собственный адаптер массива listview с рекомендуемым шаблоном, в котором говорится, что мы должны использовать метод ViewHolder внутри метода getView() для повышения производительности (и батареи?). Где я в беде, где я должен добавить слушателей к моим элементам checkboxes. Я буду более явным после того, как мой исходный адаптер списке следует файла:Адаптер адаптера пользовательского списка, предназначенный для работы: где добавить слушателей?

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 **** в комментарии к коду моего исходного файла.

Что вызывает у меня проблемы, это эффективность загрузки товаров и правильность программы (нет ошибок): следует ли добавлять элементы checkbox-слушателей при добавлении элемента управления внутри ViewHolder (раздел 1) или после загрузки каждого элемента (раздел 2)?

+1

Добавьте его в 1-ое место. Код, который устанавливает слушателей, будет называться только один раз при раздувании. – anil

+0

Давай, забудьте о держателях: они дают вам минимальное (не измеряемое) повышение производительности, см. Любые аксимирующие адаптеры, сделанные google: они используют шаблон держателя вида? NO – pskink

+2

pskink неверен; держатели обзора являются важным улучшением производительности. Что касается «Использует ли Google их?» - они явно используют _force_ их использование в новых адаптерах RecyclerView. –

ответ

1

Вы можете установить слушателей один раз при создании строк. Однако, установив их, как только вам понадобится какой-то способ узнать (внутри слушателя) , что нажал. Для этого вам нужно будет указать элемент, к которому принадлежит строка при привязке представления. Нечто похожее на это должно работать:

// 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); 

Так как вы установите позицию элемента в качестве метки на флажке при связывании вида, флажок нажмите слушатель может просто захватить эту позицию из чекбокса тега и приобретает ссылка на элемент.

В качестве альтернативы вы можете просто установить элемент как тег, а не ссылку на позицию!