Actualizar Android ListView

Tengo un Listview que tira y exhibe datos de un sqlite DB. Los datos de la primera columna del DB se muestran en el ListView y cuando se hace clic en él, se inicia una Activity muestra el resto de la columna asociada con la primera columna. Cuando los datos se editan, el ListView necesita ser actualizado para reflejar esto, pero no muestra las actualizaciones a menos que la aplicación se reinicie.

He intentado llamar, notifyDataSetChanged() y startActivityForResult() en mi método onResume() , pero que no funcionó. ¿Qué método debo usar para realizar la actualización de ListView en mi código actual?

Entiendo que se puede usar un SimpleCursorAdapter y he intentado implementar ese código sin éxito. Soy un principiante y necesito código real para entender lo que hay que hacer.

 public class LoginList extends Activity implements OnClickListener, OnItemClickListener { private ListView loginList; private Button webLogin; private ListAdapter loginListAdapter; private ArrayList<LoginDetails> loginArrayList; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.login_listview); loginList = (ListView) findViewById(R.id.loginlist); loginList.setOnItemClickListener(this); webLogin = (Button) findViewById(R.id.button3); webLogin.setOnClickListener(this); loginArrayList = new ArrayList<LoginDetails>(); loginListAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, populateList()); loginList.setAdapter(loginListAdapter); } @Override public void onClick (View v) { Intent webLoginIntent = new Intent (this, LoginPlusActivity.class); startActivity(webLoginIntent); } public List<String> populateList () { List<String> webNameList = new ArrayList<String>(); dataStore openHelperClass = new dataStore (this); SQLiteDatabase sqliteDatabase = openHelperClass.getReadableDatabase(); Cursor cursor = sqliteDatabase.query(dataStore.TABLE_NAME_INFOTABLE, null, null, null, null, null, dataStore.COLUMN_NAME_SITE, null); startManagingCursor(cursor); while (cursor.moveToNext()) { String sName = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_SITE)); String wUrl = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_ADDRESS)); String uName = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_USERNAME)); String pWord = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_PASSWORD)); String lNotes = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_NOTES)); LoginDetails lpDetails = new LoginDetails(); lpDetails.setsName(sName); lpDetails.setwUrl(wUrl); lpDetails.setuName(uName); lpDetails.setpWord(pWord); lpDetails.setlNotes(lNotes); loginArrayList.add(lpDetails); webNameList.add(sName); } sqliteDatabase.close(); return webNameList; } @Override protected void onResume() { super.onResume(); loginListAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, populateList()); loginList.setAdapter(loginListAdapter); } @Override public void onItemClick(AdapterView<?> arg0 , View arg1, int arg2, long arg3) { Toast.makeText(getApplicationContext(), "Selected ID :" + arg2, Toast.LENGTH_SHORT).show(); Intent updateDeleteLoginInfo = new Intent (this, UpdateDeleteLoginList.class); LoginDetails clickedObject = loginArrayList.get(arg2); Bundle loginBundle = new Bundle(); loginBundle.putString("clickedWebSite",clickedObject.getsName()); loginBundle.putString("clickedWebAddress",clickedObject.getwUrl()); loginBundle.putString("clickedUserName",clickedObject.getuName()); loginBundle.putString("clickedPassWord",clickedObject.getpWord()); loginBundle.putString("clickedNotes",clickedObject.getlNotes()); updateDeleteLoginInfo.putExtras(loginBundle); startActivityForResult(updateDeleteLoginInfo, 0); } } 

7 Solutions collect form web for “Actualizar Android ListView”

Esto es exactamente lo que un Loader es ideal para. Le sugiero que cree un SimpleCursorAdapter para vincular el DB a la interfaz de usuario ( ListView en este caso), un ContentProvider para interactuar con el DB y un CursorLoader para supervisar el DB para los cambios y actualizar la interfaz de usuario cuando sea necesario. El Loader manejará todos los cambios de DB y actualizará su ListView simplemente actualizando su adaptador. Parece que hay mucho trabajo por adelantado, pero es increíblemente potente una vez configurado y funcionará durante todo el ciclo de vida de Android.

Estos tutoriales deben ser útiles:

Editar

 private ArrayList<LoginDetails> loginArrayList = new ArrayList<LoginDetails>();; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.login_listview); loginList = (ListView) findViewById(R.id.loginlist); loginList.setOnItemClickListener(this); webLogin = (Button) findViewById(R.id.button3); webLogin.setOnClickListener(this); loginListAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,loginArrayList ); loginList.setAdapter(loginListAdapter); populateList(); } @Override public void onClick (View v) { Intent webLoginIntent = new Intent (this, LoginPlusActivity.class); startActivity(webLoginIntent); } public void populateList () { loginListAdapter.clear(); loginArrayList.clear(); dataStore openHelperClass = new dataStore (this); SQLiteDatabase sqliteDatabase = openHelperClass.getReadableDatabase(); Cursor cursor = sqliteDatabase.query(dataStore.TABLE_NAME_INFOTABLE, null, null, null, null, null, dataStore.COLUMN_NAME_SITE, null); startManagingCursor(cursor); while (cursor.moveToNext()) { String sName = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_SITE)); String wUrl = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_ADDRESS)); String uName = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_USERNAME)); String pWord = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_PASSWORD)); String lNotes = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_NOTES)); LoginDetails lpDetails = new LoginDetails(); lpDetails.setsName(sName); lpDetails.setwUrl(wUrl); lpDetails.setuName(uName); lpDetails.setpWord(pWord); lpDetails.setlNotes(lNotes); loginArrayList.add(lpDetails); webNameList.add(sName); } loginListAdapter.notifyDatasetChanged(); sqliteDatabase.close(); } 

Usted está perdiendo la referencia a su listview que porqué su lista no está actualizando …

Haga esta modificación en su código. 1. Inicialice su ArrayList cuando se declara (globalmente).

 ArrayList loginArrayList = new ArrayList<LoginDetails>(); 
  1. Ajustar directamente la lista de asignación a Adapter (onCreate)

    LoginListAdapter = nuevo ArrayAdapter (esto, android.R.layout.simple_list_item_1, loginArrayList);

  2. Llame a populateList() en onCreate() .

  3. En su populateList() lugar de Adding data to the new list, agregue a la lista existente asociada con su Adapter ie loginArrayList

Si su lista es completamente nueva, llame a adapter.clear() y loginArrayList.clear() en el loginArrayList.clear() populateList() antes de agregar datos al loginArrayList . Después de agregar los datos a la llamada adapter.notifyDataSetChanged()

Esto debería funcionar…

Mi recomendación.

  1. No haga un bucle para cargar su lista. Si es una lista simple con todas las cadenas. Trate de usar un SimpleCursorAdapter y hará que su aplicación sea más rápida y más corta.
  2. Una vez que actualice la base de datos, entonces lo que haces es consultar el DB para obtener el Cursor , y al uso del Adapter . swapCursor(newCursor) . Esto actualizará su lista mientras mantiene la posición de desplazamiento.

Si está creando manualmente los datos de respaldo del adaptador (en este caso está usando un ArrayAdapter – que es completamente aceptable en muchos casos), entonces cuando la base de datos cambia necesita volver a consultar la base de datos, volver a crear su conjunto de datos, cambiar El conjunto de datos de respaldo de su adaptador, e informe a la lista que el conjunto de datos ha cambiado.

Una forma de lograr esto puede ser transmitir una intención que le permita a su actividad realizar los pasos mencionados anteriormente (capturando esa intención con un BroadcastReceiver).

Aquí está mi código de ejemplo para la edición de cada fila, así como la base de datos de la lista Espero que te ayude

Primero crearé crear un nombre de adaptador "ListAdapterItem.java"

  import java.util.ArrayList; import java.util.HashMap; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.RelativeLayout; import android.widget.TextView; public class ListAdapterItem extends BaseAdapter { private ArrayList<HashMap<String, Object>> list; private Context context; private RelativeLayout ll; // used to keep selected position in ListView private int selectedPos = -1; // init value for not-selected private TextView label,label_id; String name,id; public ListAdapterItem (Context context,ArrayList<HashMap<String, Object>> list) { this.list = list; this.context = context; } public void setSelectedPosition(int pos) { selectedPos = pos; // inform the view of this change notifyDataSetChanged(); } public int getSelectedPosition() { return selectedPos; } public View getView(int position, View convertView, ViewGroup parent) { ll = (RelativeLayout) LayoutInflater.from(this.context).inflate(R.layout.data_list_item, null); // get text view label = (TextView) ll.findViewById(R.id.txtview_country_name); label_id=(TextView) ll.findViewById(R.id.txtview_id); id=list.get(position).get("Id").toString(); name = list.get(position).get("Name").toString(); label.setText(name); label_id.setText(id); return ll; } public int getCount() { return this.list.size(); } public Object getItem(int position) { return position; } public long getItemId(int position) { return position; } } 

Y aquí está mi data_list_item

  <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="fill_parent" android:orientation="vertical" android:padding="5dp"> <TextView android:id="@+id/txtview_id" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_margin="8dp" android:layout_marginRight="2dp" android:textColor="@android:color/black" android:textSize="22dp" android:visibility="invisible"/> <TextView android:id="@+id/txtview_country_name" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_margin="8dp" android:layout_marginRight="2dp" android:textColor="@android:color/black" android:textSize="22dp" /> </RelativeLayout> 

Y la clase principal "Main.java"

  public class Main extends Activity implements OnClickListener { String name; SQLiteDatabase db; Cursor cursor; private ProgressDialog progressDialog; public ListAdapterItem list_adapter; private ArrayList<HashMap<String, Object>> lst_data; private HashMap<String, Object> hm; private ListView listview; private String list_id; private int counter_id,selectedPosition; private View selectedView; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_layout); lst_data = new ArrayList<HashMap<String, Object>>(); listview = (ListView) findViewById(R.id.list); new FetchDB().execute(); } private class FetchDB extends AsyncTask<String, Void,ArrayList<HashMap<String, Object>>> { protected void onPreExecute() { progressDialog = ProgressDialog.show(Main.this,"Fetching Data", "Loading,Please wait...", true); } protected ArrayList<HashMap<String, Object>> doInBackground(String... lstStrings)throws IllegalArgumentException { try { db = openOrCreateDatabase("MyDB", MODE_PRIVATE, null); cursor = db.rawQuery("SELECT * FROM person WHERE Id <> ''",null); if (cursor != null && cursor.getCount() > 0) { if (cursor.moveToFirst()) { do { hm = new HashMap<String, Object>(); hm.put("Id",cursor.getInt(cursor.getColumnIndex("Id"))); hm.put("Name", cursor.getString(cursor.getColumnIndex("Name"))); lst_data.add(hm); } while (cursor.moveToNext()); }// end of cursor.moveToFirst() cursor.close(); } } catch (Exception e) { e.getMessage(); } db.close();// database close return lst_data; }// end of doInbackgournd @Override protected void onPostExecute(ArrayList<HashMap<String, Object>> result) { progressDialog.dismiss(); list_adapter = new ListAdapterItem(Main.this,result); listview.setAdapter(list_adapter); listview.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) { list_adapter.setSelectedPosition(arg2); selectedPosition = arg2; selectedView = arg1; list_id=((TextView) selectedView.findViewById(R.id.txtview_id)).getText().toString(); } }); } }// end of FetchDBTask private class SaveTask extends AsyncTask<String, Void,ArrayList<HashMap<String, Object>>> { @Override protected void onPreExecute() { progressDialog = ProgressDialog.show(Main.this,"Saving Data", "Loading,Please wait...", true); } protected ArrayList<HashMap<String, Object>> doInBackground(String... arg0)throws IllegalArgumentException { counter_id++; name = editext_name.getText().toString(); hm = new HashMap<String, Object>(); hm.put("Id",counter_id); hm.put("Name",name); lst_data.add(hm); saveDB(); return lst_data; }// end of doInbackgournd protected void onPostExecute(ArrayList<HashMap<String, Object>> result) { progressDialog.dismiss(); list_adapter = new ListAdapterItem(Main.this,result); listview.setAdapter(list_adapter); listview.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) { list_adapter.setSelectedPosition(arg2); selectedPosition = arg2; selectedView = arg1; list_id=((TextView) selectedView.findViewById(R.id.txtview_id)).getText().toString(); } }); } }// end of saveTask public void saveDB(){ String sql; db = openOrCreateDatabase("MyDB", MODE_PRIVATE, null); // create table if not e exist db.execSQL("CREATE TABLE IF NOT EXISTS person(Name VARCHAR ,Id INT(3));"); sql = "SELECT * FROM person WHERE Id="+list_id; //selected or click row in list item Cursor cursor = db.rawQuery(sql, null); if (cursor.moveToFirst()) { String sqlUpdate = "UPDATE person SET Name=? WHERE Id="+db_id; db.execSQL(sqlUpdate, new Object[] {db_name}); cursor.close(); db.close();// database close } else {// empty insert String sqlInsert = "INSERT INTO person VALUES (?,"+null+")"; db.execSQL(sqlInsert, new Object[] {db_name,db_address,db_phone,db_email,db_license,db_comments,db_company,db_policy,db_phone_insurance,vehc_year,vehc_make,vehc_model,vehc_license,vehc_vinnum,vehc_color,db_position }); cursor.close(); db.close();// database close } } //Edit by row private class EditData extends AsyncTask<String, Void,ArrayList<HashMap<String, Object>>> { protected void onPreExecute() { progressDialog = ProgressDialog.show(Main.this,"Saving Data", "Loading Please wait...", true); } protected ArrayList<HashMap<String, Object>> doInBackground(String... id)throws IllegalArgumentException { name = editext_name.getText().toString(); hm = new HashMap<String, Object>(); hm.put("Id",counter_id); hm.put("Name",name); lst_data.set(selectedPosition, hm); //specific row update list_id=Integer.parseInt(edit_counter); saveDB(); return lst_data; }// end of doInbackgournd protected void onPostExecute(ArrayList<HashMap<String, Object>> result) { progressDialog.dismiss(); list_adapter = new ListAdapterItem(Main.this,result); listview.setAdapter(list_adapter); } } } 

Y el archivo main_layout.xml

  <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ListView android:id="@+id/list" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:background="@android:color/transparent" android:cacheColorHint="#00000000" android:dividerHeight="2dp" android:paddingTop="8dp" android:transcriptMode="normal" /> </LinearLayout> 

Especifique su id cada listrow en el listview espero que esta respuesta a su pregunta

Creo que en el método populate () antes del bloque while debes llamar a loginListAdapter.notifyDataSetChanged () y a loginListAdapter.clear (); Eso borraría el adaptador y la notificaría de la nueva lista de datos.

El bloque se verá así:

  loginListAdapter.notifyDataSetChanged(); loginListAdapter.clear(); while (cursor.moveToNext()) { String sName = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_SITE)); String wUrl = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_ADDRESS)); String uName = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_USERNAME)); String pWord = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_PASSWORD)); String lNotes = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_NOTES)); LoginDetails lpDetails = new LoginDetails(); lpDetails.setsName(sName); lpDetails.setwUrl(wUrl); lpDetails.setuName(uName); lpDetails.setpWord(pWord); lpDetails.setlNotes(lNotes); loginArrayList.add(lpDetails); webNameList.add(sName); } 

Acabo de editar porque el orden que usted llama la notificación y claro no era correcto. La clara debe ocurrir después de la notificación, es justo lo que conseguí de mi experiencia, a menos que el adaptador no volvería a dibujar la lista.

Prueba este código

En área pública agregar variable: List<String> arrayList = new ArrayList<String>();

Y en onCreate () agregue esto:

  arrayList = populateList(); 

// entonces agrega la variable en el adaptador como esto

 loginListAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, arrayList ); 

En onResume () este código:

 @Override protected void onResume() { super.onResume(); loginArrayList.clear(); arrayList.clear(); arrayList = populateList(); loginListAdapter.notifyDataSetChanged() } 

Háganos saber si usted lo resolvió.

  • ¿Cómo actualizar ListView en ListFragment de FragmentActivity?
  • SimpleCursorAdapter en un ViewPager
  • Implementación de una vista de lista con selección múltiple con filtro utilizando un adaptador de cursor
  • Android: Utilizar SimpleCursorAdapter para obtener datos de la base de datos a ListView
  • SimpleCursorAdapter de Android con consultas utilizando DISTINCT
  • Mostrar número de contacto y nombre de contacto en una vista de lista personalizada
  • Actualizar SimpleCursorAdapter mientras mantiene la posición de desplazamiento en ListView
  • Los métodos onCreateViewHolder y onBindViewHolder de RecyclerView.Adapter no se reciben
  • Cómo establecer onClick escucha de un ImageButton en ViewBinder?
  • Enfoque para rellenar la vista de lista expandible con la base de datos SQlite local
  • ¿Usando SimpleCursorAdapter con Spinner?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.