2015-07-28 3 views
3

Я стараюсь как можно быстрее ускорить приложение, позвонив findViewById() как можно меньше в класс адаптера.Как избежать множественных вызовов findViewById() в классе адаптера?

Я слышал о «пути», где я могу создать HashMap<T>, содержащие View экземпляры и целые числа в качестве значений, и использовать его вместе или вместе с ViewHolder внутреннего класса адаптера. Как вы можете видеть, я мало слышал об этом и не имел возможности задавать больше вопросов об этом «пути».

Я искал решение в Интернете, но я либо искал неправильные ключевые слова, либо не признал решения как таковые.

Может ли кто-нибудь направить меня правильно? Может быть, кто-то пишет небольшой образец о том, как это сделать?

EDIT 1

У меня нет никаких проблем с моей нынешней ListView, как это уже с помощью ViewHolder шаблона. Причина этого вопроса была в том, что я слышал, что вы можете на самом деле увеличить скорость, используя рисунок HashMap, чем с использованием шаблона ViewHolder. Я знаю, что это неопределенное описание, но именно поэтому я пришел сюда, чтобы спросить.

Совместное использование кода не помогло бы вообще, потому что это обычный адаптер с использованием шаблона ViewHolder, как и тот, который вы использовали в общих ссылках. Никаких экспериментов или чего-то, что сделало адаптер медленным.

Говоря это снова, главная причина, чтобы спросить, это должно было найти наш, если есть шаблон быстрее, чем ViewHolder

+4

Ум, если вы уже используете 'ViewHolder', и если' ViewHolder' написан правильно, вы уже свернули свои вызовы 'findViewById()'. – CommonsWare

+0

опубликуйте некоторый код, чтобы мы могли видеть, что у вас уже есть – tyczj

+0

Возможно, ваш ум может быть настроен на это, но вы подумали о том, чтобы отступить назад и фактически измерить, есть ли проблема с производительностью с помощью findViewById(), как вы сейчас? Вы можете потратить много времени на эту оптимизацию, и, в конце концов, вы можете получить почти буквально ничто, но вместо этого угадали свой код :) – dimsuz

ответ

0

То, как уменьшить количество звонков в findViewById это в «Recycle» Просмотров с ViewHolder. Идея заключается в том, чтобы сохранить завышенные взгляды и повторно использовать их по мере необходимости - и поскольку у них уже есть ViewHolders, вам не нужно делать вызовы findViewById.

Как @nhaarman, описанный в последней части его ответа, способ сделать это для listviews - это getView, чтобы повторно использовать convertView, если он не является нулевым, и используя ссылочный вид в ViewHolder для их обновления.

Подход, как создать ViewHolder и хранить его в представлении setTag, описан в first link @nhaarman. Затем в функции getView, если convertView не является нулевым, вызовите getTag inorder, чтобы вернуть ViewHolder обратно.

В другом примечании вы должны изучить RecyclerView, который является списком, который обеспечивает использование шаблона ViewHolder.

1

Вы должны использовать парадигму ViewHolder, которая наиболее легко реализуется с помощью RecyclerView, когда задействованы адаптеры. Доступен онлайн-пример кода here и образец GitHub для клонирования через AndroidStudio напрямую или via Github.

Решение HashMap будет работать, но почему возникает проблема поиска HashMap, когда вы можете просто провести ссылку на объект? Кроме того, RecyclerView изначально обрабатывает различные виды TYPE, поэтому вам не нужно откатывать свое собственное решение, если у вас есть строки заголовков разделов, которые выглядят иначе, чем строки данных.

==================================================================================================================================== =

Более подробное объяснение RecyclerView следует на основе фрагментов из образца, к которому я привязан.

Протяните CustomAdapterRecyclerView.

public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> { 

Создать пользовательский номер ViewHolder. Он должен быть почти всегда статическим классом, если он встроен в ваш CustomAdapter.

public static class ViewHolder extends RecyclerView.ViewHolder { 
     private final TextView textView; 

     public ViewHolder(View v) { 
      super(v); 
      // Define click listener for the ViewHolder's View. 
      v.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        Log.d(TAG, "Element " + getPosition() + " clicked."); 
       } 
      }); 
      textView = (TextView) v.findViewById(R.id.textView); 

Обратите внимание, что ViewHolder находит точку в конструкторе, так как экземпляр ViewHolder привязан к View инстанции. ViewHolder должен иметь ссылки на любые элементы пользовательского интерфейса, которые вы планируете обновлять в обратном вызове onBind. Объект ViewHolder затем ассоциируется с View на RecyclerView, когда вы включаете следующий код в свой CustomAdapter.

// Create new views (invoked by the layout manager) 
@Override 
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { 
    // Create a new view. 
    View v = LayoutInflater.from(viewGroup.getContext()) 
      .inflate(R.layout.text_row_item, viewGroup, false); 

    return new ViewHolder(v); 
} 

Обратите внимание, как onCreateViewHolder обратного вызова задается параметр viewType. Текущий код всегда возвращает тот же тип настраиваемого ViewHolder, но он может предоставлять разные классы ViewHolder на основе типа (так вы поддерживаете строки, которые поддерживают разные виды). Следующий код - это то, как вы обновляете свой интерфейс, когда представление привязано к набору данных.

// Replace the contents of a view (invoked by the layout manager) 
@Override 
public void onBindViewHolder(ViewHolder viewHolder, final int position) { 
    Log.d(TAG, "Element " + position + " set."); 

    // Get element from your dataset at this position and replace the contents of the view 
    // with that element 
    viewHolder.getTextView().setText(mDataSet[position]); 
} 

С помощью этих частей в месте RecyclerView будет создавать и повторно использовать ваш Views И ViewHolders путем соответствующего типа снижения зрения иерархии внешний вид окна и потенциально делает приложение гораздо меньше «Janky».

+0

Когда я использую 'RecyclerView', я делаю то же самое :). Что вы подразумеваете под «... когда вы можете просто кешировать ссылки» – sandalone

+0

Обновлен мой ответ, чтобы быть более конкретным. – PaulR

+0

Спасибо. Уже делаю то же самое :). Я думаю, что не так быстро, как говорит CommonsWare. Кто мы сомневаемся в нем :). – sandalone

Смежные вопросы