[Android] SharedPreference ์ •๋ฆฌ

Minjun Kimยท2023๋…„ 9์›” 3์ผ
0

Android

๋ชฉ๋ก ๋ณด๊ธฐ
33/47
post-thumbnail

๐Ÿ“ SeSAC์˜ 'JetPack๊ณผ Kotlin์„ ํ™œ์šฉํ•œ Android App ๊ฐœ๋ฐœ' ๊ฐ•์ขŒ๋ฅผ ์ •๋ฆฌํ•œ ๊ธ€ ์ž…๋‹ˆ๋‹ค.


๐Ÿ“‡ Persistence ๊ฐœ์š”

๋กœ์ปฌ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์—ฌ๋Ÿฌ๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค.

  • File Read/Write

  • SharedPreference

  • Database (DBMS)

์„ธ ๊ฐ€์ง€ ๋ฐฉ๋ฒ• ๋ชจ๋‘ ์“ฐ์ธ๋‹ค.

๊ธฐ๋ณธ์ ์œผ๋กœ ๋ชจ๋“  ๊ธฐ๊ธฐ๋Š” ํŒŒ์ผ ์ฝ๊ธฐ/์“ฐ๊ธฐ ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค. ๋•Œ๋ฌธ์— ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ข…๋ฃŒ๋˜์–ด๋„ ์ž‘์„ฑํ•œ ํŒŒ์ผ์€ ์ €์žฅ๋˜๊ณ  ๋‹ค์‹œ ์ฝ์–ด ์˜ฌ ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿผ ๊ทธ๋ƒฅ File Read/Write ๋ฐฉ๋ฒ•์œผ๋กœ ๋‹ค ํ‰์น˜๋ฉด ๋˜๋Š” ๊ฒƒ ์•„๋‹ˆ๋ƒ?

์ €์žฅํ•˜๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฌธ์ž์—ด, Boolean ๊ฐ’, ์ˆซ์ž๊ฐ’ ๋“ฑ์ด๋ผ๋ฉด File Read/Write ๊ฐ€ ์•„๋‹Œ SharedPreference ๋‚˜ Database ๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. ๋ฌผ๋ก  File Read/Write ๋กœ๋„ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, SharedPreference ์™€ Database ์ชฝ์ด ํ›จ์”ฌ ์‰ฝ๋‹ค.

File Read/Write ๋Š” ์ด๋ฏธ์ง€ ๋ฐ์ดํ„ฐ์— ์‚ฌ์šฉํ•œ๋‹ค. ํŠนํžˆ ์นด๋ฉ”๋ผ ์•ฑ์„ ๋‹ค๋ฃฌ ๋•Œ ๋งŽ์ด ์‚ฌ์šฉํ•œ๋‹ค.

๐Ÿ”Ž [์ฐธ๊ณ ]

์˜์†์„ฑ(persistence)์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•œ ํ”„๋กœ๊ทธ๋žจ์˜ ์‹คํ–‰์ด ์ข…๋ฃŒ๋˜๋”๋ผ๋„ ์‚ฌ๋ผ์ง€์ง€ ์•Š๋Š” ๋ฐ์ดํ„ฐ์˜ ํŠน์„ฑ์„ ์˜๋ฏธํ•œ๋‹ค.


๐Ÿ“š File

SharedPreference ์™€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋„ ๊ฒฐ๊ตญ File ๊ณผ ๊ด€๋ จ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐœ๋…๋งŒ ์งง๊ฒŒ ์‚ดํŽด๋ณด์ž.

์ž๋ฐ” API ๋กœ File Read/Write

  • File : ํŒŒ์ผ ๋ฐ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์ง€์นญํ•˜๋Š” ํด๋ž˜์Šค

  • FileInputStream / FileOutputStream : ํŒŒ์ผ์—์„œ ๋ฐ”์ดํŠธ ์ŠคํŠธ๋ฆผ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ฑฐ๋‚˜ ์“ฐ๋Š” ํด๋ž˜์Šค

  • FileReader / FileWriter : ํŒŒ์ผ์—์„œ ๋ฌธ์ž์—ด ์ŠคํŠธ๋ฆผ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ฑฐ๋‚˜ ์“ฐ๋Š” ํด๋ž˜์Šค

โ— ์ฃผ์˜์ 

ํŒŒ์ผ์„ ์ฝ๊ธฐ/์“ฐ๊ธฐ ํ•  ๋•Œ ๋‚ด์žฅ ๋ฉ”๋ชจ๋ฆฌ์ธ์ง€ ์™ธ์žฅ ๋ฉ”๋ชจ๋ฆฌ์ธ์ง€ ๊ตฌ๋ณ„ํ•ด์•ผ ํ•œ๋‹ค.

  • ํŒŒ์ผ์ด ์ €์žฅ๋˜๋Š” ๊ณณ์„ ๋‚ด์žฅ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„ ๊ณผ ์™ธ์žฅ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„ ์œผ๋กœ ๊ตฌ๋ถ„

  • ์™ธ์žฅ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์€ ์•ฑ๋ณ„ ์ €์žฅ๊ณต๊ฐ„๊ณผ ๊ณต์œ  ์ €์žฅ๊ณต๊ฐ„์œผ๋กœ ๊ตฌ๋ถ„

โ“ ๋‚ด์žฅ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์ด๋ž€?

val file = File(filesDir, "test.txt")
val writeStream: OutputStreamWriter = file.writer()
writeStream.write("hello world")
writeStream.flush()
  • ๋‚ด์žฅ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์ด๋ž€ ์•ฑ์ด ์„ค์น˜๋˜๋ฉด ์‹œ์Šคํ…œ์—์„œ ์ž๋™์œผ๋กœ ํ• ๋‹นํ•˜๋Š” ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„

  • ์•ฑ์˜ ํŒจํ‚ค์ง€๋ช…์œผ๋กœ ํด๋”๋ฅผ ๋งŒ๋“ค์–ด ์ฃผ๋ฉฐ ์ด ํด๋”๊ฐ€ ์ด ์•ฑ์˜ ๋‚ด์žฅ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„

  • filesDir ๋ผ๋Š” ํ”„๋กœํผํ‹ฐ๋กœ ๋‚ด์žฅ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์ž„์„ ์ง€์ •ํ•œ๋‹ค.


๐Ÿ“š SharedPreference

  • ๋ฐ์ดํ„ฐ๋ฅผ ํ‚ค-๊ฐ’ ํ˜•ํƒœ๋กœ ์ €์žฅ (Map)

  • ๋‚ด๋ถ€์ ์œผ๋กœ ๋‚ด์žฅ ๋ฉ”๋ชจ๋ฆฌ์˜ ์•ฑ ํด๋”์— XML ํŒŒ์ผ๋กœ ๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ

XML ํ˜•ํƒœ๋กœ ํŒŒ์ผ์ด ์ €์žฅ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฏธ์ง€ ์ €์žฅ์—๋Š” ์ ํ•ฉํ•˜์ง€ ์•Š๋‹ค.

๐Ÿ“Œ Preference ๊ฐ์ฒด ํš๋“

2๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.

๐Ÿ“‘ Activity.getPreferences (int mode)

  • ํ•˜๋‚˜์˜ ์•กํ‹ฐ๋น„ํ‹ฐ๋ฅผ ์œ„ํ•œ ๋ฐ์ดํ„ฐ ์ €์žฅ์„ ๋ชฉ์ , ๋•Œ๋ฌธ์— ๋งค๊ฐœ๋ณ€์ˆ˜์— ํŒŒ์ผ๋ช…์ด ์—†๋‹ค.

  • ์ด ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•œ ์•กํ‹ฐ๋น„ํ‹ฐ ํด๋ž˜์Šค๋ช…์œผ๋กœ XML ํŒŒ์ผ๋ช…์ด ๋งŒ๋“ค์–ด ์ง

์ฆ‰, ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ „์—ญ์˜ ๋ฐ์ดํ„ฐ ์ €์žฅ์„ ๋ชฉ์ ์œผ๋กœ ํ•˜์ง€ ์•Š๋Š”๋‹ค. ๊ทธ๋ž˜์„œ SharedPreference ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ด๋‹ค.

๐Ÿ“‘ Context.getSharedPreferences (String name, int mode)

val sharedPref = getSharedPreferences("my_prefs", Context.MODE_PRIVATE)
  • ์•ฑ ์ „์ฒด์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํ‚ค-๊ฐ’ ํ˜•ํƒœ๋กœ ์ €์žฅ

  • ๋ฒ”์œ„๊ฐ€ ์ „์—ญ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋งค๊ฐœ๋ณ€์ˆ˜์— ํŒŒ์ผ๋ช…์ด ๋“ค์–ด๊ฐ„๋‹ค.

๐Ÿ“Œ ๋ฐ์ดํ„ฐ ์ €์žฅ

๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” SharedPreferences.Editor ํด๋ž˜์Šค์˜ ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•œ๋‹ค.

SharedPreferences.Editor ๊ฐ์ฒด๋Š” SharedPreferences ์˜ edit() ํ•จ์ˆ˜๋กœ ํš๋“ํ•œ๋‹ค.

commit() ํ•˜๋Š” ์ˆœ๊ฐ„ ์ €์žฅ๋œ๋‹ค.

  • putBoolean(String key, Boolean value)

  • putInt(String key, Int value)

  • putFloat(String key, Float value)

  • putLong(String key, Long value)

  • putString(String key, String value)

๐Ÿ“Œ ๋ฐ์ดํ„ฐ ํš๋“

๋ฐ์ดํ„ฐ ํš๋“์€ SharedPreferences ์˜ getter ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•œ๋‹ค.

  • getBoolean(String key, Boolean defvalue)

  • getInt(String key, Int defvalue)

  • getFloat(String key, Float defvalue)

  • getLong(String key, Long defvalue)

  • getString(String key, String defvalue)

๐Ÿงฉ ์‹ค์Šต ์˜ˆ์ œ

  • activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/editView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <CheckBox
        android:id="@+id/checkView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="check" />

    <Button
        android:id="@+id/saveButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="SAVE" />

    <Button
        android:id="@+id/getButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Get Data" />

    <TextView
        android:id="@+id/resultView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />


</LinearLayout>


  • MainActivity.kt
package com.kotdev99.android.c55

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

		val editView = findViewById<EditText>(R.id.editView)
		val checkView = findViewById<CheckBox>(R.id.checkView)
		val saveButton = findViewById<Button>(R.id.saveButton)
		val getButton = findViewById<Button>(R.id.getButton)
		val resultView = findViewById<TextView>(R.id.resultView)

		val sharedPref = getSharedPreferences("my_prefs", Context.MODE_PRIVATE)

		saveButton.setOnClickListener {
			sharedPref.edit().run {
				putString("data1", editView.text.toString())
				putBoolean("data2", checkView.isChecked)
				commit()
			}
		}

		getButton.setOnClickListener {
			val data1 = sharedPref.getString("data1", "none")
			val data2 = sharedPref.getBoolean("data2", false)
			resultView.text = "data1: ${data1}, data2: ${data2}"
		}
	}
}

๐Ÿ“ฒ ๊ฒฐ๊ณผ


๐Ÿ“š Settings XML

์•ฑ์˜ ํ™˜๊ฒฝ์„ค์ • ์ž๋™ํ™”๋ฅผ ๋ชฉ์ ์œผ๋กœ ํ•œ๋‹ค.

์•ฑ์— ๋Œ€ํ•œ ํ™˜๊ฒฝ์„ค์ •์„ ์œ„ํ•ด์„œ๋Š” ์šฐ์„  ์„ค์ •์„ ์ถœ๋ ฅํ•  ์•กํ‹ฐ๋น„ํ‹ฐ๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํ™˜๊ฒฝ์„ค์ • ์•กํ‹ฐ๋น„ํ‹ฐ์—์„œ ๋ฐœ์ƒํ•œ ์œ ์ € ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ  ์„ค์ • ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๊ธฐ์— ์˜์†์ ์œผ๋กœ ์ €์žฅํ•ด์•ผ ํ•œ๋‹ค.
์ฆ‰, UI ์•กํ‹ฐ๋น„ํ‹ฐ + ์œ ์ € ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ + Persistence ๋ฅผ ๋˜! ์ถ”๊ฐ€๋กœ! ๊ตฌํ˜„ํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

ํ•˜์ง€๋งŒ Settings XML ์„ ์‚ฌ์šฉํ•˜๋ฉด ์œ„์˜ ๊ณผ์ •์ด ์ž๋™ํ™” ๋œ๋‹ค. ์ผ์ผํžˆ ์•กํ‹ฐ๋น„ํ‹ฐ UI๋ฅผ ๊ตฌ์„ฑํ•˜์ง€ ์•Š์•„๋„, ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ ๋กœ์ง์„ ์ž‘์„ฑํ•˜์ง€ ์•Š์•„๋„, ์˜์†์  ์ €์žฅ ์ฝ”๋“œ๋ฅผ ์งœ์ง€ ์•Š์•„๋„, Settings XML ์ด ์•Œ์•„์„œ ๋งŒ๋“ค์–ด ์ค€๋‹ค. ๋ฌผ๋ก  SharedPreference๋กœ ํ™˜๊ฒฝ์„ค์ •์„ ๊ตฌํ˜„ํ•  ์ˆ˜๋Š” ์žˆ๋‹ค.

๐Ÿ“ ์ž‘์„ฑ ๋ฐฉ๋ฒ•

๐Ÿ“Œ ์˜์กด์„ฑ ์ถ”๊ฐ€

implementation("androidx.preference:preference-ktx:1.2.0")
  • ์•ฑ ์„ค์ •์„ ์œ„ํ•œ XML ์ž‘์„ฑ

  • API Level 29 ์ด์ „ ๋ฒ„์ „์—์„œ๋Š” PreferenceFragment ์„ ์ด์šฉ

  • API Level 29 ๋ฒ„์ „๋ถ€ํ„ฐ AndroidX Preference ๋ฅผ ์ด์šฉํ•  ๊ฒƒ์„ ๊ถŒ์žฅ

๐Ÿ“Œ XML ํŒŒ์ผ ์ƒ์„ฑ

ํ™˜๊ฒฝ์„ค์ •์„ ์œ„ํ•œ ํŠน์ • ๋””๋ ‰ํ† ๋ฆฌ๋Š” ์—†๋‹ค. xml ํด๋”์— ์งฌ ๋•Œ๋ฆฌ๋ฉด ๋œ๋‹ค.

  • res/xml ํด๋”์— ์„ค์ •๊ณผ ๊ด€๋ จ๋œ XML ํŒŒ์ผ ์ž‘์„ฑ

๐Ÿ“Œ XML ์ž‘์„ฑ

<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">
	<SwitchPreferenceCompat
    	app:key="notifications"
        app:title="Enable message notifications"/>
        
</PreferenceScreen>        
  • ๋ฃจํŠธ ํƒœ๊ทธ๊ฐ€ <PreferenceScreen>

  • <SwitchPreferenceCompat> , <Preference> ๋“ฑ์˜ ํƒœ๊ทธ๋ฅผ ์ด์šฉํ•ด ๊ฐ๊ฐ์˜ ์„ค์ • ํ•ญ๋ชฉ์„ ์ค€๋น„

๐Ÿ“Œ XML ํŒŒ์ผ ์ ์šฉ

class SettingsFragment : PreferenceFragmentCompat() {
	override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
    	setPreferencesFromResource(R.xml.settings, rootKey)
	}        
}        
  • PreferenceFragmentCompat ์„ ์ƒ์†๋ฐ›์€ Fragment ๋กœ ์„ค์ • XML ์ ์šฉ

  • ๋งค๊ฐœ๋ณ€์ˆ˜ R.xml.settings ์— ์„ค์ • XML ํŒŒ์ผ๋งŒ ์ง€์ •ํ•˜๋ฉด ๋

๐Ÿงท ์„ค์ • ํƒœ๊ทธ

PreferenceScreen : ์„ค์ • ํ™”๋ฉด๋‹จ์œ„. ์ค‘์ฒฉ ๊ฐ€๋Šฅํ•˜๋ฉฐ ์ค‘์ฒฉ๋œ ๋‚ด์šฉ์€ ๋ณ„๋„์˜ ํ™”๋ฉด์— ๋‚˜์˜ด.

PreferenceCategory : ์„ค์ • ์—ฌ๋Ÿฌ๊ฐœ๋ฅผ ์‹œ๊ฐ์ ์œผ๋กœ ๋ฌถ์–ด์„œ ํ‘œํ˜„

CheckboxPreference : ์ฒดํฌ๋ฐ•์Šค๊ฐ€ ๋‚˜์˜ค๋Š” ์„ค์ •

EditTextPreference : ๊ธ€ ์ž…๋ ฅ์„ ์œ„ํ•œ ์„ค์ •

ListPreference : ํ•ญ๋ชฉ Dialog ์„ ์œ„ํ•œ ์„ค์ •

MultiSelectListPreference : ํ•ญ๋ชฉ Dialog ์ธ๋ฐ ์ฒดํฌ๋ฐ•์Šค๊ฐ€ ์ž๋™ ์ถ”๊ฐ€๋˜์–ด ๋‹ค์ค‘ ์„ ํƒ ๊ฐ€๋Šฅ

RingtonPreference : Rington ์„ ํƒ์„ ์œ„ํ•œ ์„ค์ •

SwitchPreference : Switch ์„ ์ด์šฉํ•œ ์„ค์ •

๐Ÿงฉ ์‹ค์Šต ์˜ˆ์ œ

res/xml ํ•˜์œ„์— ํ™˜๊ฒฝ์„ค์ • XML ํŒŒ์ผ ์ƒ์„ฑ

  • settings.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <PreferenceCategory>
        app:key="a_category"
        app:title="A Setting">
        <SwitchPreferenceCompat
            app:key="a1"
            app:title="A - 1 Setting" />
        <SwitchPreferenceCompat
            app:key="a2"
            app:title="A - 2 Setting" />
    </PreferenceCategory>
    <PreferenceCategory>
        app:key="B_category"
        app:title="B Setting">
        <SwitchPreferenceCompat
            app:key="b1"
            app:title="B - 1 Setting" />
    </PreferenceCategory>
</PreferenceScreen>

XML ํŒŒ์ผ์„ ์ ์šฉํ•œ ํ”„๋ž˜๊ทธ๋จผํŠธ๋ฅผ ๋„์šธ ์•กํ‹ฐ๋น„ํ‹ฐ ๋ ˆ์ด์•„์›ƒ ์ž‘์„ฑ

  • activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    class="com.kotdev99.android.c56.SettingsFragment" />

XML ํŒŒ์ผ์„ ์ ์šฉํ•  ํ”„๋ž˜๊ทธ๋จผํŠธ ์ž‘์„ฑ

  • SettingsFragment.kt
package com.kotdev99.android.c56

class SettingsFragment : PreferenceFragmentCompat() {
	override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
		setPreferencesFromResource(R.xml.settings, rootKey)
	}
}

๐Ÿ“ฒ ๊ฒฐ๊ณผ


๐Ÿ“š PreferenceFragmentCompat

  • ์„ค์ •์„ ์œ„ํ•œ XML ๋งŒ ๋งŒ๋“ค์–ด ์ ์šฉ์‹œ์ผœ ์ฃผ๋ฉด ์„ค์ • ํ™”๋ฉด์ด ๋‚˜์˜ค๊ณ  ์œ ์ €๊ฐ€ ์„ค์ • ํ•ญ๋ชฉ์„ ํด๋ฆญํ•˜๋ฉด ์„ค์ • ๋‚ด์šฉ์ด ์ž๋™์œผ๋กœ ์ €์žฅ

  • ์–ด๋–ค ๊ฒฝ์šฐ์—๋Š” ์„ค์ • XML ์˜ ์„ค์ • ๋ถ€๋ถ„์„ ์ฝ”๋“œ์—์„œ ์ œ์–ด ํ•„์š”

  • ์„ค์ • ํ•ญ๋ชฉ์„ ํด๋ฆญํ•˜๋Š” ์ˆœ๊ฐ„์˜ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ  ์‹ถ๊ฑฐ๋‚˜ ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜์–ด ๋ฐœ์ƒํ•œ ๊ฒฐ๊ณผ๋ฅผ ์„ค์ • ํ•ญ๋ชฉ์˜ title ํ˜น์€ summary ๋กœ ์ง€์ •ํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ

Settings XML ์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋ณธ ๊ธฐ๋Šฅ ์ด์™ธ์— ํ•„์š”ํ•˜๋‹ค๋ฉด ์‚ฌ์šฉํ•˜์ž.

๐Ÿ“ ์ž‘์„ฑ ๋ฐฉ๋ฒ•

๐Ÿ“Œ ํƒœ๊ทธ ๊ฐ์ฒด ํš๋“

<EditTextPreference
	android:key="id"
    android:title="ID ์„ค์ •"
    android:isPreferenceVisible="false"/>
val idPreference: EditTextPreference? = findPreference("id")
idPreference?.isVisible = true
  • ์„ค์ •์„ ์œ„ํ•ด ์‚ฌ์šฉํ•œ ํƒœ๊ทธ์— ํ•ด๋‹น๋˜๋Š” ๊ฐ์ฒด๋ฅผ findPreference() ํƒœ๊ทธ๋กœ ํš๋“

๐Ÿ“Œ SimpleSummaryProvider

์„ค์ • ํ•ญ๋ชฉ์„ ์„ ํƒํ•œ ํ›„์—๋„ "ํ•ญ๋ชฉ์„ ์„ ํƒ ํ•ด์ฃผ์„ธ์š”" ๋ผ๋Š” ๋ฌธ๊ตฌ๊ฐ€ ์ถœ๋ ฅ๋˜๋ฉด ๋ฌด์–ธ๊ฐ€ ์ด์ƒํ•˜๋‹ค.

๊ทธ๋ž˜์„œ ์ด๋ฏธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— Summary ๊ฐ’์„ ์ž๋™์œผ๋กœ ๋ณ€๊ฒฝ์ฃผ๋Š” ํด๋ž˜์Šค๊ฐ€ ์ค€๋น„๋˜์–ด ์žˆ๋‹ค.

soundPreference!!.setSummaryProvider(ListPreference.SimpleSummaryProvider.getInstance())
  • <EditTextPreference> , <ListPreference> ์— ์˜ํ•œ ์„ค์ •ํ•œ ๊ฐ’ ํ™”๋ฉด์— ์ถœ๋ ฅ

  • SimpleSummaryProvider ์ด์šฉ

SimpleSummaryProvider ๋Š” ์œ ์ €๊ฐ€ ์ž…๋ ฅํ•œ ๊ฐ’์„ ์ž๋™์œผ๋กœ Summary ์— ์จ์ค€๋‹ค.

๐Ÿ“Œ ์ปค์Šคํ…€ SummaryProvider

idPreference?.summaryProvider=
	Preference.SummaryProvider<EditTextPreference> { preference ->
    	val text = preference.text
        if (TextUtils.isEmpty(thext)) {
        	"์„ค์ •์ด ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค."
		} else {
        	"์„ค์ •๋œ ID๊ฐ’์€ : $text ์ž…๋‹ˆ๋‹ค."
		}
	}
  • SummaryProvider ์˜ ํ•˜์œ„ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด ์ฝ”๋“œ์—์„œ ์›ํ•˜๋Š” ๋Œ€๋กœ summary ์ง€์ • ๊ฐ€๋Šฅ

๐Ÿ“Œ onPreferenceClick

์œ ์ €๊ฐ€ ์„ค์ • ํ•ญ๋ชฉ์„ ๋ˆ„๋ฅด๋Š” ์ˆœ๊ฐ„์„ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ

idPreference?.setOnPreferenceClickListener {
	true
}
  • ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋ฉด setOnPreferenceClickListener() ์„ ์ด์šฉํ•ด ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ง€์ •

๐Ÿ“Œ onPreferenceChange

์œ ์ €๊ฐ€ ์„ค์ • ๊ฐ’์„ ๋ณ€๊ฒฝํ•œ ์ˆœ๊ฐ„์„ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ

idPreference?.setOnPreferenceChangeListener { preference, newValue ->
	Log.d("kotdev", "preference key : ${preference.key}, newValue : $newValue")
	true
}
  • ์œ ์ €๊ฐ€ ์„ค์ •์„ ๋ณ€๊ฒฝํ•œ ์ˆœ๊ฐ„์„ ๊ฐ์ง€ํ•ด ๋ณ€๊ฒฝํ•œ ๊ฐ’์„ ์ด์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ

  • Preference.OnPreferenceChangeListener ๋ฅผ ์ด์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๊ฐ Preference ๊ฐ์ฒด์— ์ ์šฉ

  • SharedPreferences.OnSharedPreferenceChangeListener ๋Š” ๋ชจ๋“  ์„ค์ • ๊ฐ์ฒด์˜ ๋ณ€๊ฒฝ์„ ํ•˜๋‚˜์˜ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ์—์„œ ๊ฐ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•

  • ์„ค์ •ํ•œ ๊ฐ’์ด ๋งค๊ฐœ๋ณ€์ˆ˜ newValue ๋กœ ๋„˜์–ด์˜จ๋‹ค.

๐Ÿงฉ ์‹ค์Šต ์˜ˆ์ œ

res/xml ํ•˜์œ„์— ํ™˜๊ฒฝ์„ค์ • XML ํŒŒ์ผ ์ƒ์„ฑ

  • settings.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <SwitchPreferenceCompat
        android:key="serverFlag"
        android:summaryOff="์„œ๋ฒ„ ์—ฐ๋™์ด ๋น„ํ™œ์„ฑํ™” ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค"
        android:summaryOn="์„œ๋ฒ„ ์—ฐ๋™์ด ํ™œ์„ฑํ™” ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค"
        android:title="์„œ๋ฒ„์—ฐ๋™" />

    <PreferenceCategory
        android:dependency="serverFlag"
        android:title="์„œ๋ฒ„์—ฐ๋™์ •๋ณด">
        <EditTextPreference
            android:key="serverId"
            android:title="ID" />
        <ListPreference
            android:entries="@array/array_voice"
            android:entryValues="@array/array_voice"
            android:key="sound_list"
            android:title="์„œ๋ฒ„ ๋ฉ”์‹œ์ง€ ์•Œ๋ฆผ์Œ" />
    </PreferenceCategory>
</PreferenceScreen>

ListPreference ํ•ญ๋ชฉ์— ์ถœ๋ ฅํ•  ๋ฌธ์ž์—ด ๋ฐฐ์—ด์„ XML ํŒŒ์ผ๋กœ ์ž‘์„ฑ. res/values ํ•˜์œ„์— ์ƒ์„ฑํ•œ๋‹ค.

  • arrays.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="array_voice">
        <item>์นดํ†ก</item>
        <item>์นดํ†ก์™”์ˆ‘</item>
        <item>์นด์นด์˜คํ†ก</item>
    </string-array>
</resources>

XML ํŒŒ์ผ์„ ์ ์šฉํ•œ ํ”„๋ž˜๊ทธ๋จผํŠธ๋ฅผ ๋„์šธ ์•กํ‹ฐ๋น„ํ‹ฐ ๋ ˆ์ด์•„์›ƒ ์ž‘์„ฑ

  • activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    class="com.kotdev99.android.c57.SettingFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

XML ํŒŒ์ผ์„ ์ ์šฉํ•  ํ”„๋ž˜๊ทธ๋จผํŠธ ์ž‘์„ฑ

  • SettingsFragment.kt
package com.kotdev99.android.c57

class SettingFragment : PreferenceFragmentCompat() {
	override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
		setPreferencesFromResource(R.xml.settings, rootKey)

		val idPreference = findPreference<EditTextPreference>("serverId")
		val soundPreference = findPreference<ListPreference>("sound_list")

		idPreference?.setOnPreferenceChangeListener { preference, newValue ->
			Toast.makeText(activity, "$newValue", Toast.LENGTH_SHORT).show()
			true
		}

		soundPreference!!.summaryProvider = ListPreference.SimpleSummaryProvider.getInstance()
		idPreference!!.summaryProvider =
			Preference.SummaryProvider<EditTextPreference> { preference ->
				val text = preference.text
				if (TextUtils.isEmpty(text)) {
					"์„ค์ • ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค"
				} else {
					"์„ค์ •๋œ id ๊ฐ’์€ $text ์ž…๋‹ˆ๋‹ค."
				}
			}
	}
}

๐Ÿ“ฒ ๊ฒฐ๊ณผ

์—…๋กœ๋“œ์ค‘..

profile
์‘์•  ๋‚˜ ์•„๊ธฐ ๋‰ด๋น„

0๊ฐœ์˜ ๋Œ“๊ธ€