Android ListView Actualizar una sola fila

Después de haber obtenido los datos de una sola fila de un ListView , quiero actualizar esa única fila.

Actualmente estoy usando notifyDataSetChanged(); Pero eso hace que la View reaccione muy lentamente. ¿Hay alguna otra solución?

Una opción es manipular el ListView directamente. Primero verifique si el índice de la fila actualizada está entre getFirstVisiblePosition() y getLastVisiblePosition() , estos dos le dan la primera y la última posición en el adaptador que son visibles en la pantalla. A continuación, puede obtener la fila View con getChildAt(int index) y cambiarlo.

Como explicó Romain Guy hace un tiempo durante la sesión de E / S de Google , la forma más eficiente de actualizar una vista en una vista de lista es algo como lo siguiente (esto actualiza los datos de toda la vista):

 ListView list = getListView(); int start = list.getFirstVisiblePosition(); for(int i=start, j=list.getLastVisiblePosition();i<=j;i++) if(target==list.getItemAtPosition(i)){ View view = list.getChildAt(i-start); list.getAdapter().getView(i, view, list); break; } 

Suponiendo que el target es un elemento del adaptador.

Este código recupera el ListView , luego navega por las vistas mostradas actualmente, compara el elemento de target que buscas con cada elemento de vista visualizado y si el destino está entre esos, obtén la vista getView y ejecuta el adaptador getView en esa vista para actualizar la vista. monitor.

Como una nota de lado invalidate no funciona como algunas personas esperan y no refrescar la vista como getView hace, notifyDataSetChanged reconstruirá la lista completa y terminará llamando a getview para cada elementos mostrados y invalidateViews también afectará a un montón.

Una última cosa, uno también puede obtener un rendimiento extra si sólo necesita cambiar un niño de una vista de fila y no toda la fila como getView hace. En ese caso, el siguiente código puede reemplazar list.getAdapter().getView(i, view, list); (Ejemplo para cambiar un texto TextView ):

 ((TextView)view.findViewById(R.id.myid)).setText("some new text"); 

En código confiamos en.

Este método más sencillo funciona bien para mí, y solo necesitas conocer el índice de posición para obtener la vista:

 // mListView is an instance variable private void updateItemAtPosition(int position) { int visiblePosition = mListView.getFirstVisiblePosition(); View view = mListView.getChildAt(position - visiblePosition); mListView.getAdapter().getView(position, view, mListView); } 

El siguiente código funcionó para mí. Tenga en cuenta al llamar a GetChild () tiene que compensar por el primer elemento de la lista ya que su relación con eso.

 int iFirst = getFirstVisiblePosition(); int iLast = getLastVisiblePosition(); if ( indexToChange >= numberOfRowsInSection() ) { Log.i( "MyApp", "Invalid index. Row Count = " + numberOfRowsInSection() ); } else { if ( ( index >= iFirst ) && ( index <= iLast ) ) { // get the view at the position being updated - need to adjust index based on first in the list View vw = getChildAt( sysvar_index - iFirst ); if ( null != vw ) { // get the text view for the view TextView tv = (TextView) vw.findViewById(com.android.myapp.R.id.scrollingListRowTextView ); if ( tv != null ) { // update the text, invalidation seems to be automatic tv.setText( "Item = " + myAppGetItem( index ) + ". Index = " + index + ". First = " + iFirst + ". Last = " + iLast ); } } } } 

Hay otra cosa mucho más eficiente que puede hacer, si se ajusta a su caso de uso que es.

Si está cambiando el estado y puede de alguna manera llamar a la adecuada (conociendo la posición) mListView.getAdapter().getView() será el más eficiente de todos.

Puedo demostrar una manera realmente fácil de hacerlo creando una clase interna anónima en mi clase ListAdapter.getView() . En este ejemplo, tengo un TextView mostrando un texto "nuevo" y esa vista se establece en GONE cuando se hace clic en el elemento de lista:

 @Override public View getView(int position, View convertView, ViewGroup parent) { // assign the view we are converting to a local variable View view = convertView; Object quotation = getItem(position); // first check to see if the view is null. if so, we have to inflate it. if (view == null) view = mInflater.inflate(R.layout.list_item_quotation, parent, false); final TextView newTextView = (TextView) view.findViewById(R.id.newTextView); view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (mCallbacks != null) mCallbacks.onItemSelected(quotation.id); if (!quotation.isRead()) { servicesSingleton.setQuotationStatusReadRequest(quotation.id); quotation.setStatusRead(); newTextView.setVisibility(View.GONE); } } }); if(quotation.isRead()) newTextView.setVisibility(View.GONE); else newTextView.setVisibility(View.VISIBLE); return view; } 

El marco utiliza automáticamente la position correcta y tiene que preocuparse por volver a getView antes de llamar a getView .

Sólo para que conste, ¿alguien consideró la vista 'Ver' en el método de anulación?

  public void onItemClick(AdapterView<?> parent, View view, int position, long id) { //Update the selected item ((TextView)view.findViewById(R.id.cardText2)).setText("done!"); } 
  • Androide WebView alternativa para webapps
  • Problema de rendimiento de PublisherAdView loadAd en Android
  • Forzar Renderscript para que se ejecute en CPU o GPU (Atleast para fines de ajuste de rendimiento)
  • ¿Cómo almacenar en caché y almacenar objetos y establecer una política de expiración en android?
  • La almohadilla de firma es lenta en android
  • La notificación con setGroupSummary (true) no está visible en Android N
  • No se puede ejecutar "ANY" reaccionar proyecto ejemplo nativo
  • Throwable: No se pudo crear la tarjeta SD
  • Android Studio demasiado lento y laggy
  • Hashmap vs Bundle en Android Eficiencia y comparación de rendimiento
  • Aplicación de Android onLowMemory () en la API> = 14
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.