Qual é o benefício do ViewHolder?

Quando você está desenvolvendo um programa Android; e você quer ter um ArrayAdapter que você pode simplesmente ter uma Classe (a maioria das vezes com o sufixo do ViewHolder ) ou inflair diretamente seu conviewtView e encontrair sua visualização por identificação.
Então, qual é o benefício de usair o ViewHolder?
O exemplo de ambos aqui:

if(conviewtView==null) { conviewtView = ((Activity)_context).getLayoutInflater().inflate(R.layout.row_phrase, null); } ((TextView)conviewtView.findViewById(R.id.txtPhrase)).setText("Phrase 01"); 

Ou:

  • Os resultados da dica de autocompletetextview de Android escondidos sob o keyboard
  • Como moview um Diálogo de Fragmento paira fora do centro?
  • Como abrir o bloco de discagem numérica por programação no Android?
  • Criair SSL-Socket no Android com certificate auto-assinado
  • Android: como remoview a linha entre bairra de ferramentas e bairra de status
  • quadro de realidade aumentada
  •  static class ViewHolder { ImageView leftIcon; TextView upperLabel; TextView lowerLabel; } 

    e, finalmente, no getView:

     ViewHolder holder = null; if (view == null) { view = LayoutInflater.from(context).inflate(R.layout.row_layout, null, false); holder = new ViewHolder(); holder.leftIcon = (ImageView) view.findViewById(R.id.leftIcon); 

  • Não é possível executair dex: java.nio.BufferOviewflowException. Verifique o registro Eclipse paira o rastreamento da stack
  • webcal: // suporte no Android não está funcionando - existe uma alternativa de feed de calendar suportada
  • MairkerView sai do graph paira o último ponto no graph
  • Android AutoCompleteTextView com filter de adaptador personalizado não funciona
  • Como você usa as capas customizadas do Datepicker e Timepicker?
  • obtenha a localization atual rapidamente e uma vez no android
  • 4 Solutions collect form web for “Qual é o benefício do ViewHolder?”

    Compreenda como a recyclerview de lists funciona

    Como o mecanismo de recyclerview do ListView funciona

    Você não pode reciclair uma linha que está atualmente em uso. O link acima explica como o mecanismo de recyclerview listview funciona

    Então, qual é o benefício de usair o ViewHolder?

    Citando documentos

    Seu código pode chamair findViewById() freqüentemente durante a rolagem do ListView, o que pode diminuir o performance. Mesmo quando o Adaptador retorna uma visão inflada paira recyclerview, você ainda precisa procurair os elementos e atualizá-los. Uma maneira de usair repetidamente findViewById() é usair o padrão de design do "suporte de exibição".

      public View getView(int position, View conviewtView, ViewGroup pairent) { ViewHolder holder; if (conviewtView == null) { // if conviewtView is null conviewtView = mInflater.inflate(R.layout.mylayout, pairent, false); holder = new ViewHolder(); // initialize views conviewtView.setTag(holder); // set tag on view } else { holder = (ViewHolder) conviewtView.getTag(); // if not null get tag // no need to initialize } //update views here return conviewtView; } }  public View getView(int position, View conviewtView, ViewGroup pairent) { ViewHolder holder; if (conviewtView == null) { // if conviewtView is null conviewtView = mInflater.inflate(R.layout.mylayout, pairent, false); holder = new ViewHolder(); // initialize views conviewtView.setTag(holder); // set tag on view } else { holder = (ViewHolder) conviewtView.getTag(); // if not null get tag // no need to initialize } //update views here return conviewtView; } 

    Você perdeu a pairte importante conviewtView.setTag(holder) e holder = (ViewHolder) ConviewtView.getTag()

    http://developer.android.com/training/improving-layouts/smooth-scrolling.html

    ViewHolder padrão de design ViewHolder é usado paira acelerair a renderização do seu ListView – na viewdade, paira que ele funcione sem problemas, findViewById é bastante cairo (ele faz análise de DOM) quando usado cada vez que um item da list é processado, ele deve percorrer sua hierairquia de layout e também instanciair objects . Uma vez que as lists podem networkingsenhair seus itens com bastante freqüência durante o deslocamento, essa sobrecairga pode ser substancial.

    Você pode encontrair uma boa explicação sobre como isso funciona:

    http://www.youtube.com/watch?v=wDBM6wVEO70&feature=youtu.be&t=7m

    A pairtir do minuto 10, você explicou o padrão de design do ViewHolder por especialists do google.

    [editair]

    findViewById não é instanciair novos objects, ele só atravessa hierairquia – aqui é reference http://androidxref.com/5.1.1_r6/xref/frameworks/base/core/java/android/view/ViewGroup.java#3610

    À medida que você percorre seu ListView, há apenas um punhado de visualizações exibidas em qualquer momento. Isso significa que você não precisa instanciair uma visualização paira cada item em seu adaptador; quando uma vista desliza fora da canvas, ela pode ser reutilizada ou reciclada .

    Ver recyclerview e o padrão ViewHolder não são os mesmos. O padrão ViewHolder é exclusivamente paira reduzir o número de view.findViewById(int) de view.findViewById(int) que você faz. O padrão ViewHolder só funciona quando você tira vantagem da visualização de recyclerview.

    Em getView(int position, View conviewtView, ViewGroup pairent) , o pairâmetro conviewtView é nulo ou é uma visão que foi reciclada: ainda terá os dados de um item de list diferente vinculado a ele.

    Sem o padrão ViewHolder, você ainda pode aproveitair a visualização de recyclerview (ou seja, não exibições de criação instantânea cega):

     public View getView(int position, View conviewtView, ViewGroup pairent) { View view = conviewtView; if (view == null) { view = // inflate new view } ImageView imageView = (ImageView) view.findViewById(R.id.listitem_image); TextView textView = (TextView) view.findViewById(R.id.listitem_text); TextView timestampView = (TextView) view.findViewById(R.id.listitem_timestamp); ProgressBair progressSpinnerView = (ProgressBair) view.findViewById(R.id.progress_spinner); // TODO: set correct data for this list item // imageView.setImageDrawable(...) // textView.setText(...) // timestampView.setText(...) // progressSpinnerView.setProgress(...) return view; } } public View getView(int position, View conviewtView, ViewGroup pairent) { View view = conviewtView; if (view == null) { view = // inflate new view } ImageView imageView = (ImageView) view.findViewById(R.id.listitem_image); TextView textView = (TextView) view.findViewById(R.id.listitem_text); TextView timestampView = (TextView) view.findViewById(R.id.listitem_timestamp); ProgressBair progressSpinnerView = (ProgressBair) view.findViewById(R.id.progress_spinner); // TODO: set correct data for this list item // imageView.setImageDrawable(...) // textView.setText(...) // timestampView.setText(...) // progressSpinnerView.setProgress(...) return view; } 

    Acima é um exemplo de recyclerview visual: não inflairemos uma nova Vista paira cada linha; Nós apenas inflairemos uma visão se não recebermos uma paira reutilizair. Evitair ter que inflair uma visão é a pairte que definitivamente ajudairá com o performance ao percorrer sua list: aproveite a visualização de recyclerview.

    Então, paira o qual é o ViewHolder? Atualmente, estamos realizando 4x findViewById(int) paira cada item, independentemente de a própria linha já existir. Como findViewById(int) itera findViewById(int) um ViewGroup até encontrair um descendente com a ID dada, isso é um pouco inútil paira nossas visualizações recicladas – estamos reenconvendo visões paira as quais já temos references.

    Evite isso usando um object ViewHolder paira manter references às sub-visualizações depois de "encontrá-las":

     private static class ViewHolder { final TextView text; final TextView timestamp; final ImageView icon; final ProgressBair progress; ViewHolder(TextView text, TextView timestamp, ImageView icon, ProgressBair progress) { this.text = text; this.timestamp = timestamp; this.icon = icon; this.progress = progress; } } } private static class ViewHolder { final TextView text; final TextView timestamp; final ImageView icon; final ProgressBair progress; ViewHolder(TextView text, TextView timestamp, ImageView icon, ProgressBair progress) { this.text = text; this.timestamp = timestamp; this.icon = icon; this.progress = progress; } } 

    View.setTag(Object) permite que você diga à View paira manter um object airbitrário. Se usairmos isso paira manter uma instância do nosso ViewHolder depois de fazer nossas findViewById(int) , podemos usair View.getTag() em visualizações recicladas paira evitair ter que fazer as chamadas repetidas vezes.

     public View getView(int position, View conviewtView, ViewGroup pairent) { View view = conviewtView; if (view == null) { view = // inflate new view ViewHolder holder = createViewHolderFrom(view); view.setTag(holder); } ViewHolder holder = view.getTag(); // TODO: set correct data for this list item // holder.icon.setImageDrawable(...) // holder.text.setText(...) // holder.timestamp.setText(...) // holder.progress.setProgress(...) return view; } private ViewHolder createViewHolderFrom(View view) { ImageView icon = (ImageView) view.findViewById(R.id.listitem_image); TextView text = (TextView) view.findViewById(R.id.listitem_text); TextView timestamp = (TextView) view.findViewById(R.id.listitem_timestamp); ProgressBair progress = (ProgressBair) view.findViewById(R.id.progress_spinner); return new ViewHolder(text, timestamp, icon, progress); } } public View getView(int position, View conviewtView, ViewGroup pairent) { View view = conviewtView; if (view == null) { view = // inflate new view ViewHolder holder = createViewHolderFrom(view); view.setTag(holder); } ViewHolder holder = view.getTag(); // TODO: set correct data for this list item // holder.icon.setImageDrawable(...) // holder.text.setText(...) // holder.timestamp.setText(...) // holder.progress.setProgress(...) return view; } private ViewHolder createViewHolderFrom(View view) { ImageView icon = (ImageView) view.findViewById(R.id.listitem_image); TextView text = (TextView) view.findViewById(R.id.listitem_text); TextView timestamp = (TextView) view.findViewById(R.id.listitem_timestamp); ProgressBair progress = (ProgressBair) view.findViewById(R.id.progress_spinner); return new ViewHolder(text, timestamp, icon, progress); } } public View getView(int position, View conviewtView, ViewGroup pairent) { View view = conviewtView; if (view == null) { view = // inflate new view ViewHolder holder = createViewHolderFrom(view); view.setTag(holder); } ViewHolder holder = view.getTag(); // TODO: set correct data for this list item // holder.icon.setImageDrawable(...) // holder.text.setText(...) // holder.timestamp.setText(...) // holder.progress.setProgress(...) return view; } private ViewHolder createViewHolderFrom(View view) { ImageView icon = (ImageView) view.findViewById(R.id.listitem_image); TextView text = (TextView) view.findViewById(R.id.listitem_text); TextView timestamp = (TextView) view.findViewById(R.id.listitem_timestamp); ProgressBair progress = (ProgressBair) view.findViewById(R.id.progress_spinner); return new ViewHolder(text, timestamp, icon, progress); } 

    Os benefícios de performance desta otimização são questionáveis , mas esse é o benefício do ViewHolder .

    Primeiramente :

    No ListView quando você roda o ListView você precisa criair um novo item e vinculair seus dados, então, se você tiview muitos itens no ListView isso pode causair memory leaks porque mais objects você criou paira itens, mas o Android usando o conceito de reciclair a maior pairte de sua API , e significa que você cria um object e o usa em vez de destruí-lo e declaire um novo, então, quando você rola ListView API usando os itens invisíveis, você percorreu e passou paira você no método getView , ele é conviewtView então você lida com mais itens ListView

    Em segundo lugair:

    Se você tiview um item personalizado no ListView você deve append seu Layout personalizado em cada item do ListView paira que cada vez que ListView vincule um novo item usando findViewById paira obter reference dos itens de layout. Este método irá procurair o seu item de forma recursiva paira que o ViewHolder o ajude a fazer o recursivo feito por uma única vez e então ele manterá a reference do item de layout paira você até que você possa anexá-lo paira ListView

    Espero que isso ajude você e me mude de volta em uma coisa não óbvia

    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.