3

我正在创建一个待办事项列表。现在我的应用程序在 ListView 中添加和删除数据。但是,当我关闭我的应用程序时,数据会被删除。我想使用 SharedPreferences 来保存数据 onDestroy(),然后当我的应用程序打开时,我希望重新加载数据。

但是,我不知道如何完成这项任务。 任何人都可以帮助我使用共享首选项(也就是我正在寻找代码)保存 ListView 吗?

只有一个共享偏好的教程我希望在我的应用程序关闭时动态添加多个字符串。然后当我重新打开它时,数据就会出现。我只使用一个活动页面,一切都会发生在一页上。

这是我的代码:

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;
}
} 
4

3 回答 3

5

正如Stefano Munarini 所建议的,您可以使用数据库。

另一方面,您可以循环您的 ArrayAdapter 的元素(包装您的 ArrayList)并将它们存储到您的 SharedPreferences 中,如下所示:

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.
    }
}

一些考虑:

  • 将 SharedPreferences 保存在 onPause() 而不是 onDestroy() 中,这不能保证被调用。请参阅活动生命周期以供参考。
  • 禁止用户输入空字符串。(编辑:你已经在这样做了。)
  • 如果您知道不会有 2 个相同的字符串(禁止或其他方式),您可以使用SharedPreferences.Editor.putStringSet(String, Set<String>)来使用单个条目。
  • 如果有很多元素,或者如果您计划添加额外的选项(即截止日期、类别等),您应该真正考虑数据库选项,因为 SharedPreferences 解决方案不能提供良好的可伸缩性。
于 2013-09-09T18:34:35.843 回答
3

Android SharedPreferences 用于存储单个键值对数据。换句话说,它不是用来存储重复和复杂的数据。在您的情况下,列表视图可能包含超过 100 行或更多行,具体取决于您的应用程序。如果您要为每一行创建一个 SharedPreferences 对象,它将是 100+,这根本没有效率。解决方案如上所述,是使用 Android 的 SQLite 数据库。

一个很好的教程:http ://www.androidhive.info/2011/11/android-sqlite-database-tutorial/

于 2014-03-04T16:36:06.123 回答
1

我知道它很旧,但我想为那些仍然想使用 sharepref 并看到这篇文章的人分享我的解决方案。

1)创建扩展 ArrayAdapter 的自定义类并覆盖 toString 方法。只需在每行之间附加并放置“,”。

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)将数据保存为一个字符串。把它放在 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) 在 onResume 中,通过使用 ',' 将字符串连接起来恢复数据并将其添加到适配器。

    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);
            }
        }
    }
于 2015-05-22T00:32:26.960 回答