Kotlin SharedPreferences - Save ListView items and

2020-02-15 12:04发布

问题:

I have a ListView with items created by

 val values = ArrayList<String>().toMutableList()
 val adapter = ArrayAdapter(this, R.layout.listview_text_color, values)

 adapter.add(title_editText.text!!.toString() + " - " + content_editText.text!!.toString())

I need to save those ListView items and reload them again when reopen the app using SharedPreferences (not DB)

This is my actual code about SP:

fun saveData(values: Set<String>) {
    val sharedPref = this.getPreferences(Context.MODE_PRIVATE) ?: return
    with(sharedPref.edit()) {
        putStringSet("test", values)
        putString("title", title_editText.text!!.toString())
        putString("content", content_editText.text!!.toString())
        apply()
    }
}

fun getData() {
    val sharedPref = this.getPreferences(Context.MODE_PRIVATE) ?: return
    val titleData = sharedPref.getString("title", "")
    val contentData = sharedPref.getString("content", "")
    Toast.makeText(this, "$titleData $contentData", Toast.LENGTH_LONG).show()

}

EDIT FOR SOLUTION

After full days of research, I went to solution:

In MainActivity.kt create you ArrayList variable as global:

    class MainActivity : AppCompatActivity() {

    private var values = ArrayList<String>()

    ... //the rest of your code
}

Then add those 2 functions:

 private fun saveData() {
    val sharedPreferences = getSharedPreferences("shared preferences", MODE_PRIVATE)
    val editor = sharedPreferences.edit()
    val gson = Gson()
    val json = gson.toJson(values)
    editor.putString("task list", json)
    editor.apply()
}

private fun loadData() {
    val sharedPreferences = getSharedPreferences("shared preferences", MODE_PRIVATE)
    val gson = Gson()
    val json = sharedPreferences.getString("task list", "")
    val type = object: TypeToken<ArrayList<String>>() {
    }.type

   if(json == null)
       values = ArrayList()
   else
      values = gson.fromJson(json, type)
}

where values is your ArrayList

To save data:

done_fab.setOnClickListener {

        values.add("put your string here")
        adapter.notifyDataSetChanged() //your array adapter
        saveData()
    }

And to load data, simply call the function in your MainActivity:

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        loadData()

         val adapter = ArrayAdapter(this, R.layout.listview_text_color, values) //your custom arrayAdapter for the listView

        ... //the rest of your code
}

回答1:

Thank you Arfrmann for posting a working resolution that I could use. I had to modify the code to fit inside a Fragment as well as my values being a MutableList of integers. So, I thought I'd share my scenario so that others could benefit.

class NeedsmetFragment : Fragment() {

    private var incorrectList = mutableListOf<Int>()
    val PREFS_FILENAME = "com.app.app.prefs"

    private fun saveData() {
        val sharedPreferences = context!!.getSharedPreferences(PREFS_FILENAME, 0)
        val editor = sharedPreferences.edit()
        val gson = Gson()
        val json = gson.toJson(incorrectList)
        editor.putString("incorrectList", json)
        editor.apply()
    }

    private fun loadData() {
        val sharedPreferences = context!!.getSharedPreferences(PREFS_FILENAME, 0)
        val gson = Gson()
        val json = sharedPreferences.getString("incorrectList", "")
        val type = object: TypeToken<MutableList<Int>>() {}.type

        if(json == null || json == "")
            incorrectList = mutableListOf<Int>()

        else
            incorrectList = gson.fromJson(json, type)
    }
    //...
    x++

    incorrestList.add(x)
    saveData()


    loadData()
    thisval = incorrectList[x]


}


回答2:

The proper way to save ArrayList of String to preferences is:

.putStringArrayList("test", values)

and get it

.getStringArrayList("test")


回答3:

SOLUTION

After full days of research, I went to solution:

In MainActivity.kt create you ArrayList variable as global:

    class MainActivity : AppCompatActivity() {

    private var values = ArrayList<String>()

    ... //the rest of your code
}

Then add those 2 functions:

 private fun saveData() {
    val sharedPreferences = getSharedPreferences("shared preferences", MODE_PRIVATE)
    val editor = sharedPreferences.edit()
    val gson = Gson()
    val json = gson.toJson(values)
    editor.putString("task list", json)
    editor.apply()
}

private fun loadData() {
    val sharedPreferences = getSharedPreferences("shared preferences", MODE_PRIVATE)
    val gson = Gson()
    val json = sharedPreferences.getString("task list", "")
    val type = object: TypeToken<ArrayList<String>>() {
    }.type

   if(json == null)
       values = ArrayList()
   else
      values = gson.fromJson(json, type)
}

where values is your ArrayList

To save data:

done_fab.setOnClickListener {

        values.add("put your string here")
        adapter.notifyDataSetChanged() //your array adapter
        saveData()
    }

And to load data, simply call the function in your MainActivity:

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        loadData()

         val adapter = ArrayAdapter(this, R.layout.listview_text_color, values) //your custom arrayAdapter for the listView

        ... //the rest of your code
}

All this because SharedPreferences doesn't supports ArrayList<String> storing, so passing them with a JSON is the best option