2010-11-16 11 views
48

Mi libro, "Hola Android" da esto como una manera de utilizar un ayudante db costumbre, la creación de un cursor, y luego la creación de un adaptador de la siguiente manera:mejor manera de refrescar adaptador/ListView en Android

Cursor cursor 
CustomDatabaseHelper test = new CustomDatabaseHelper(this); 
try { 
     cursor = getData(); 
     showData(cursor); 
} finally { 
     test.close(); 
} 

Sin embargo, cada vez que necesito actualizar el conjunto de datos, necesito seguir ejecutando este bloque de código (lo que se vuelve un poco difícil dentro de un onClick() para un botón porque "esto" no está disponible.

¿Es esta la mejor manera de actualizar el conjunto de datos, o debo mirar hacia la eliminación de .close y emitir un adaptador.notifyDataSetChanged()? Si hago esto, a veces obtengo una fuerza cercana como (y no puedo recuerde por el momento) pero a veces no se puede eliminar correctamente. Creo que esto puede deberse a que la base de datos está actualmente abierta e intenta abrir nuevamente.

¿Deberíamos también estar declarando las variables para los cursores, DatabaseHelpers y Adapter en la clase (fuera de OnCreate) para que estén accesibles para todas las funciones?

Me doy cuenta de que esta es solo una programación deficiente en esta etapa, pero estoy tratando de obtener algunos consejos sobre la mejor manera de hacer las cosas.

+0

Sólo una nota al margen: Las cosas son un poco diferentes si utiliza proveedores de contenido y LoaderManager. Ver: http://stackoverflow.com/a/19657500/1087411 – Anderson

Respuesta

81

Debe usar adapter.notifyDataSetChanged(). ¿Qué dice el registro cuando usas eso?

+1

Gracias Macarse, Eso funciona, pero solo si no hago un cierre en el ayudante de la base de datos. También creo que sucede lo que sucede si no hago el .close, el sistema intenta abrir demasiadas bases de datos y se cae. ¿Debería la base de datos estar abierta en todo el ciclo de vida de la actividad, entonces? – Simon

+0

Debe usar http://developer.android.com/reference/android/app/Activity.html#startManagingCursor(android.database.Cursor) para administrar su cursor dentro de una Actividad. – Macarse

9

siguiente código funciona perfecto para mí

EfficientAdapter adp = (EfficientAdapter) QuickList.getAdapter(); 
adp.UpdateDataList(EfficientAdapter.MY_DATA); 
adp.notifyDataSetChanged(); 
QuickList.invalidateViews(); 
QuickList.scrollBy(0, 0); 
+1

Llamar notifyDataSetChanged() no fue suficiente para mí. invalidateViews() en su lugar funciona. –

16

sólo tiene que añadir estos códigos antes de Adapter que está funcionando para mí:

listView.destroyDrawingCache(); 
    listView.setVisibility(ListView.INVISIBLE); 
    listView.setVisibility(ListView.VISIBLE); 

o directamente se puede utilizar a continuación método después de cambiar los datos de recursos.

adapter.notifyDataSetChanged() 
+1

Esto también se aplica a los botones: \t \t // Force refresh \t \t myButton.setVisibility (Button.INVISIBLE); \t \t myButton.setVisibility (Button.VISIBLE); – hornetbzz

+1

¿para qué tiene que actualizar su botón? – sravan

+0

después de un filtro y luego se aplica su reverso. – hornetbzz

0

Si está utilizando LoaderManager tratar con esta declaración:

getLoaderManager().restartLoader(0, null, this); 
-2

acaba de escribir en su ArrayAdaper personalizado este código:

public void swapItems(ArrayList<Item> arrayList) { 
    this.clear(); 
    this.addAll(arrayList); 
} 
0
adapter.notifyDataSetChanged(); 
+0

Por favor edite con más información. Se desalientan las respuestas de solo código y "prueba esto", ya que no contienen contenido que se pueda buscar y no explican por qué alguien debe "probar esto". – abarisone

+0

en la búsqueda ¿Desea actualizar el adaptador? –

0

Tal vez su problema es el momento en que la búsqueda se realiza en la base de datos. En sus ciclos Fragmento Anulación de su Fragment.java de averiguar: tratar las pruebas con los métodos:

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) { 
    View rootView = inflater.inflate(R.layout.fragment_x, container, false); //Your query and ListView code probably will be here 
    Log.i("FragmentX", "Step OnCreateView");// Try with it 
    return rootView; 
} 

Trate de manera similar puso Log.i ... "onStart" y "onResume".

Finalmente cortar el código en "onCreate" e lo puso en "onStart", por ejemplo:

@Override 
public void onStart(){ 
    super.onStart(); 
    Log.i("FragmentX","Step OnStart"); 
    dbManager = new DBManager(getContext()); 
    Cursor cursor = dbManager.getAllNames(); 
    listView = (ListView)getView().findViewById(R.id.lvNames); 
    adapter = new CustomCursorAdapter(getContext(),cursor,0);// your adapter 
    adapter.notifyDataSetChanged(); 
    listView.setAdapter(adapter); 
} 
0

Sólo tiene que escribir en su encargo ArrayAdaper este código:

private List<Cart_items> customListviewList ; 

refreshEvents(carts); 

public void refreshEvents(List<Cart_items> events) 
{ 
    this.customListviewList.clear(); 
    this.customListviewList.addAll(events); 
    notifyDataSetChanged(); 
} 
5

mejor manera de Actualizar el adaptador/ListView en Android

No solo llamando al notifyDataSetChanged() refrescará los datos ListView, setAdapter() debe llamarse antes de cargar la información correctamente:

listView.setAdapter(adapter); 
    adapter.notifyDataSetChanged(); 
Cuestiones relacionadas