Chapters

Hide chapters

Android Apprentice

Third Edition · Android 10 · Kotlin 1.3 · Android Studio 3.6

Before You Begin

Section 0: 4 chapters
Show chapters Hide chapters

Section II: Building a List App

Section 2: 7 chapters
Show chapters Hide chapters

Section III: Creating Map-Based Apps

Section 3: 7 chapters
Show chapters Hide chapters

8. SharedPreferences
Written by Darryl Bayliss

Heads up... You're reading this book for free, with parts of this chapter shown beyond this point as scrambled text.

In the previous chapter, you set up an Activity to use a RecyclerView.

In this chapter, you’ll update Listmaker to create, save, and delete lists. You’ll show these lists in the RecyclerView created in the last chapter. You’ll also learn about a new topic called SharedPreferences, a simple way to save data about your app.

By the end of the chapter, you’ll know:

  • What SharedPreferences are
  • How to use SharedPreferences to save and retrieve objects

Getting started

If you’re following along with your own project, open it and keep using it with this chapter. If not, don’t worry. Locate the projects folder for this chapter and open the Listmaker app inside the starter folder.

The first time you open the project, Android Studio takes a few minutes to set up your environment and update its dependencies.

With the Listmaker project open in Android Studio, run the project using a device or emulator.

Notice the round turqoise button in the bottom right? That’s called a Floating Action Button, better known as a FAB. You use a FAB to highlight an important action on the screen.

Creating lists is the most important action in Listmaker, so it makes sense to use a FAB to add new lists. The icon in the FAB doesn’t convey well the action of adding a new list, so your first task is to select an appropriate icon.

Open activity_main.xml, and in the Component Tree window, select the Floating Action Button.

In the Attributes window on the right-hand side of Android Studio, locate the srcCompat text field. This is where you assign the image to the button. Currently, it has a value of @android:drawable/ic_dialog_email.

Change the value in srcCompat to @android:drawable/ic_menu_add and press Enter. The image in the FAB changes to a more appropriate plus sign icon.

With the icon changed, Users can better understand the purpose of this button. In the next part, you’ll add the code that allows users to create a new list.

Adding a Dialog

When users tap the FAB in Listmaker, you want the button to open a Dialog where they can enter a name for their new list. The Dialog will contain labels to prompt users for information.

<string name="name_of_list">What is the name of your list?</string>
<string name="create_list">Create</string>
private fun showCreateListDialog() {
  // 1
  val dialogTitle = getString(R.string.name_of_list)
  val positiveButtonTitle = getString(R.string.create_list)

  // 2
  val builder = AlertDialog.Builder(this)
  val listTitleEditText = EditText(this)
  listTitleEditText.inputType = InputType.TYPE_CLASS_TEXT

  builder.setTitle(dialogTitle)
  builder.setView(listTitleEditText)

  // 3
  builder.setPositiveButton(positiveButtonTitle) { dialog, _ ->
    dialog.dismiss()
  }

  // 4
  builder.create().show()
}
fab.setOnClickListener {
  showCreateListDialog()
}

Creating a list

Start by creating a model for a list to use throughout the app.

class TaskList(val name: String, val tasks: ArrayList<String> = ArrayList()) {

}

implementation 'androidx.preference:preference:1.1.0'

class ListDataManager(private val context: Context) {
  fun saveList(list: TaskList) {
    // 1
    val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context).edit()
    // 2
    sharedPreferences.putStringSet(list.name, list.tasks.toHashSet())
    // 3
    sharedPreferences.apply()
  }
}
fun readLists(): ArrayList<TaskList> {
  // 1
  val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
  // 2
  val sharedPreferenceContents = sharedPreferences.all
  // 3
  val taskLists = ArrayList<TaskList>()

  // 4
  for (taskList in sharedPreferenceContents) {

    val itemsHashSet = ArrayList(taskList.value as HashSet<String>)
    val list = TaskList(taskList.key, itemsHashSet)
    // 5
    taskLists.add(list)
  }

  // 6
  return taskLists
}

Hooking up the Activity

In the previous section, you created ListDataManager to read and write the lists Listmaker creates. In this section, you’ll begin to use it.

val listDataManager: ListDataManager = ListDataManager(this)
builder.setPositiveButton(positiveButtonTitle) { dialog, _ ->
  val list = TaskList(listTitleEditText.text.toString())
  listDataManager.saveList(list)

  val recyclerAdapter = listsRecyclerView.adapter as ListSelectionRecyclerViewAdapter
  recyclerAdapter.addList(list)

  dialog.dismiss()
}
// 1
val lists = listDataManager.readLists()
listsRecyclerView = findViewById<RecyclerView>(R.id.lists_recyclerview)
listsRecyclerView.layoutManager = LinearLayoutManager(this)

// 2
listsRecyclerView.adapter = ListSelectionRecyclerViewAdapter(lists)
class ListSelectionRecyclerViewAdapter(private val lists : ArrayList<TaskList>) : RecyclerView.Adapter<ListSelectionViewHolder>() {
override fun onBindViewHolder(holder: ListSelectionViewHolder, position: Int) {
  holder.listPosition.text = (position + 1).toString()
  holder.listTitle.text = lists.get(position).name
}
override fun getItemCount(): Int {
   return lists.size
}
fun addList(list: TaskList) {
  // 1
  lists.add(list)

  // 2
  notifyItemInserted(lists.size-1)
}

Where to go from here?

SharedPreferences is the simplest way to persist values in an Android app, so it’s worth keeping in your toolbox.

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2024 Kodeco Inc.

You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a Kodeco Personal Plan.

Unlock now