Guardar y volver a cargar ListView utilizando las preferencias compartidas

Estoy creando una lista de tareas pendientes. En este momento mi aplicación agrega y elimina datos de y hacia un ListView. Sin embargo, cuando cierro mi aplicación los datos se borran. Quiero usar SharedPreferences para guardar los datos onDestroy (), y cuando abra mi aplicación, quería que los datos se volvieran a cargar.

Sin embargo, no sé cómo llevar a cabo esta tarea. ¿Puede alguien ayudarme con guardar un ListView usando preferencias compartidas (aka que estoy buscando código)?

Hay tutoriales para una sola preferencia compartida que estoy buscando para añadir dinámicamente varias cadenas cuando mi aplicación se cierra. Luego, cuando lo vuelva a abrir, aparecerán los datos. Sólo utilizo una página de ACTIVITY, todo ocurrirá en una página.

AQUÍ ESTÁ MI CÓDIGO:

public class Main_ToDoList extends Activity implements OnClickListener { private Button btnAdd; private EditText et; private ListView lv; ArrayList<String> list = new ArrayList<String>(); ArrayAdapter<String> adapter; final Context context = this; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_activity); btnAdd = (Button)findViewById(R.id.addTaskBtn); btnAdd.setOnClickListener(this); et = (EditText)findViewById(R.id.editText); adapter = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, list); // set the lv variable to your list in the xml lv=(ListView)findViewById(R.id.list); lv.setAdapter(adapter); // set ListView item listener lv.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, final int position, long id) { AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context); alertDialogBuilder.setTitle("Confirm Delete"); alertDialogBuilder.setMessage("Sure you want to delete?"); alertDialogBuilder.setCancelable(false); alertDialogBuilder.setPositiveButton("Yes", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { adapter.remove(adapter.getItem(position)); } }); alertDialogBuilder.setNegativeButton("No", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { dialogInterface.cancel(); } }); AlertDialog alertDialog = alertDialogBuilder.create(); alertDialog.show(); } }); } public void onClick(View v) { String input = et.getText().toString(); if(input.length() > 0) { adapter.add(input); et.setText(""); } } @Override public void onDestroy() { super.onDestroy(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main__to_do_list, menu); return true; } } 

Android SharedPreferences se utiliza para almacenar un solo valor clave de datos emparejados. En otras palabras, no se hace para almacenar datos repetitivos y complejos. En su caso, una vista de lista puede contener más de 100 filas o más depende de su aplicación. Si usted creara un objeto SharedPreferences para cada fila sería 100+ de él, que no es eficiente en absoluto. La solución para esto es como se sugirió anteriormente, es utilizar la base de datos SQLite de Android.

Un buen tutorial: http://www.androidhive.info/2011/11/android-sqlite-database-tutorial/

Como sugiere Stefano Munarini , puede utilizar una base de datos.

Por otro lado, puedes realizar bucle sobre los elementos de tu ArrayAdapter (envolviendo tu ArrayList) y almacenarlos en tu SharedPreferences como en:

 public static final String PREFERENCES_TODO = "TODO_List_Shared_Preferences"; // ... SharedPreferences prefs = context.getSharedPreferences(PREFERENCES_TODO, MODE_PRIVATE); SharedPreferences.Editor editor = prefs.edit(); // This will remove all entries of the specific SharedPreferences editor.clear(); for (int i = 0; i < adapter.getCount(); ++i){ // This assumes you only have the list items in the SharedPreferences. editor.putString(String.valueOf(i), adapter.getItem(i)); } editor.commit(); // ... // And the reverse process: SharedPreferences prefs = context.getSharedPreferences(PREFERENCES_TODO, MODE_PRIVATE); for (int i = 0;; ++i){ final String str = prefs.getString(Integer.valueOf(i), ""); if (!str.equals("")){ adapter.add(str); } else { break; // Empty String means the default value was returned. } } 

Algunas consideraciones:

  • Guardar SharedPreferences en onPause () en lugar de en onDestroy () que no se garantiza que se llame. Vea el ciclo de vida de la actividad como referencia.
  • Prohíba que el usuario ingrese una cadena vacía. (Edit: Ya lo estás haciendo.)
  • Si sabe que no habrá 2 cadenas idénticas (prohibidas o no), puede usar SharedPreferences.Editor.putStringSet(String, Set<String>) para usar una sola entrada.
  • Si hay muchos elementos o si está planeando agregar opciones adicionales (por ejemplo, fecha de vencimiento, categoría, etc.) Debería considerar las opciones de base de datos ya que la solución SharedPreferences no proporciona una buena escalabilidad.

Sé que es viejo, pero quiero compartir mi solución para aquellos que todavía quieren utilizar sharepref y ver esta publicación.

1) cree una clase personalizada que extienda ArrayAdapter y reemplace el método toString. Agregue y coloque ',' entre cada línea.

 public class GroceryArrayAdapter extends ArrayAdapter<String> { public GroceryArrayAdapter(Context context, int resource) { super(context, resource); } public GroceryArrayAdapter(Context context, int resource, int textViewResourceId) { super(context, resource, textViewResourceId); } public GroceryArrayAdapter(Context context, int resource, int textViewResourceId, String[] objects) { super(context, resource, textViewResourceId, objects); } public GroceryArrayAdapter(Context context, int resource, String[] objects) { super(context, resource, objects); } public GroceryArrayAdapter(Context context, int resource, List<String> objects) { super(context, resource, objects); } public GroceryArrayAdapter(Context context, int resource, int textViewResourceId, List<String> objects) { super(context, resource, textViewResourceId, objects); } @Override public String toString(){ String data = ""; for (int i = 0; i < getCount(); i++) { data += getItem(i).toString() ; if( i + 1 < getCount()){ data += ","; } } return data; } } 

2) Guarde los datos como una cadena. ponlo en onPause ()

  private void saveData(){ sharedPrefs = activity.getSharedPreferences(Constants.APPSharePref, Context.MODE_PRIVATE); SharedPreferences.Editor e = sharedPrefs.edit(); e.putString(Constants.GROCERY,**grocery_adapter.toString()**); e.commit(); } 

3) En onResume restaurar los datos de nuevo splinting la cadena con ',' y añadirlo al adaptador.

  private void loadDataFromPref(){ sharedPrefs = getActivity().getSharedPreferences(Constants.APPSharePref, Context.MODE_PRIVATE); String gList =sharedPrefs.getString(Constants.GROCERY,""); if(!"".equals(gList) && ""!=gList){ String [] str = gList.split(","); for (String item : str) { grocery_adapter.add(item); } } } 
  • Casilla de verificación desmarcada cuando hago scrolllistview en Android
  • Android listview item altura
  • Cómo hacer una cabecera de sección en ListView que siempre se pega en la parte superior?
  • ¿Cambiar el estado del CheckBox en el elemento de lista?
  • Flujo de trabajo de facturación en la aplicación en un ListView
  • ListView de Android con casilla de verificación Eliminar / obtener ID de fila
  • Android - autoLink
  • Checkbox 'Checked' en ListView se restaura después de desplazarse
  • Mostrar menú contextual bajo demanda en Android
  • ¿Cómo afectar a elementos fuera de un listview cuando se hace clic en algunos elementos de la vista de lista?
  • Fila listView personalizada con casilla de verificación y marcas de verificación de ahorros en la rotación
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.