코딩하는 개굴이

[안드로이드] PreferenceFragmentCompat 를 이용해 설정 화면 간단하게 구현하기 본문

안드로이드

[안드로이드] PreferenceFragmentCompat 를 이용해 설정 화면 간단하게 구현하기

개굴이모자 2023. 1. 15. 21:58
반응형

앱의 설정 화면은 개발자로써 제일 필요하면서 제일 구현하기 꺼려지는 것이기도 하다.

항목에 대해 일일이 이벤트를 넣어야하기 때문인데, 심지어는 DB 혹은 Preference 를 쓰기에 간단하지만 귀찮기 그지없다.

보통, 특정 설정 값을 사용자로부터 세팅 받고 그것을 계속 저장하며 그에 따른 앱의 동작을 제공해야 하는 단순한 동작을 하는데,

이를 쉽게 구현하는 방법인 PreferenceFragmentComponent에 대해 알아보도록 하자.

 

 

PreferenceFragment 란?

설정 화면이 크고 복잡할 경우 사용자는 원하는 세팅을 쉽게 찾거나, 개발자는 이러한 화면을 구성하기 어렵다. 다라서, 이런 구성을 쉽게 수행하기 위해 Preference Library 에서는 PreferenceFragmentCompat 으로 설정 화면을 아래와 같이 간단하고 쉽게 구현할 수 있게 제공하고 있다.

 

Preference는 API Level 29 에 Deprecated 되었으므로, AndroidX Preference Library 를 추가해주어야한다.

 

 

Implementation 추가하기

implementation 'androidx.preference:preference:1.1.0'

implementation은 간단하게 preference library 사용을 위해 한 줄만 추가해 주면 된다.

 

 

XML 구성

<PreferenceScreen
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <PreferenceCategory
        app:key="setting_category"
        app:title="Notifications">

        <SwitchPreferenceCompat
            app:key="notifications"
            app:title="Enable message notifications"/>
		<EditTextPreference
			app:key="signature"
			app:title="Put your signature"/>

    </PreferenceCategory>

    <PreferenceCategory
        app:key="help_category"
        app:title="Help">

        <Preference
            app:key="feedback"
            app:summary="Report technical issues or suggest new features"
            app:title="Send feedback"/>

    </PreferenceCategory>

</PreferenceScreen>

xml 의 예시 구성은 위와 같다. 이를 구성하기 위해서는 아래의 내용을 참고해야한다.

  • 해당 xml 리소스는 res/xml 디렉토리 하위에 있어야한다.
  • root 태그는 항상 PreferenceScreen이어야한다.
  • 만일 연관성이 있는 설정들이 있다면 PreferenceCategory 로 묶을 수 있다.
  • SwitchPreferenceCompat, Preference 등은 특정 키를 가지고 있으며, 이는 유니크해야한다.
  • 그 외의 사용 가능한 preference 타입을은 가이드를 참고하길 바란다.
 

Preference components and attributes  |  Android Developers

Stay organized with collections Save and categorize content based on your preferences. Preference components and attributes   Part of Android Jetpack. This topic describes some of the most commonly-used Preference components and attributes used when buil

developer.android.com

 

 

💡 이전 버전의 Preference 에서는 PreferenceScreen 하위에 중첩되게 PreferenceScreen 을 추가해 다른 화면으로 이동할 수 있도록 구현할 수 있었지만 androidx 에서는 그렇지 않다.
만일 다른 화면을 구성하고 싶다면 하위에 Fragment 오브젝트를 추가하거나, 별도의 PreferenceFragmentComponent 를 추가한 Fragment 를 생성해서 이동시켜야한다.

 

Inflate 하기

생성한 xml 을 inflate 하기 윟해 PreferenceFragmentCompat 을 상속하는 fragment 를 생성한다.

onCreatePreferences 를 오버라이드하고, xml 을 아래와 같이 inflate 시킨다.

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

그리고, 원하는 액티비티에 Fragment 를 추가한다.

class MySettingsActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        supportFragmentManager
                .beginTransaction()
                .replace(R.id.settings_container, MySettingsFragment())
                .commit()
    }
}

 

 

Preference 다루기

위의 예시 xml 에서 EditTextPreference 를 사용했는데 해당 Preference 를 가져와보도록 하자.

MySettingFragment 의 onCreatePreferences 에서 key 값으로 해당 Preference 를 찾을 수 있다.

그리고, 동일한 키 값으로 PreferenceManager 로 해당 값을 찾아올 수도 있다.

override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
    setPreferencesFromResource(R.xml.preferences, rootKey)
    val signaturePreference: EditTextPreference? = findPreference("signature")
    // do something with this preference like ...
		// controlling visible or
		signaturePreference?.isVisible = false
		// setting summary 
		signaturePreference?.summaryProvider = SummaryProvider<EditTextPreference> { preference ->
    val text = preference.text
    if (TextUtils.isEmpty(text)) {
        "Signature not set"
    } else {
        "Your signature: " + text
    }

		//if you want to read this preference value like when the screen is shown, you can read like this
		val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this /* Activity context */)
		val name = sharedPreferences.getString("signature", "")
}

 

 

Preference 의 변경 감지하기

특정 Preference 의 변경을 감지하고 싶을 경우 OnPreferenceChangeListener 를 사용할 수 있다. 이를 이용해 특정 설정 값의 변경으로 인해 같이 변경되어야하는 것의 처리가 수행될 수 있다. (예를 들어 테마를 변경한다거나, 세팅 데이터 값을 바꾸는 등)

findPreference<EditTextPreference>("signature")?.apply {
                setOnPreferenceChangeListener { preference, newValue ->
									...
								}
}
모든 preference 의 변경을 감지하고 싶을 경우는 OnSharedPreferenceChangeListener 를 사용할 수도 있다.

 

 

참고 링크

반응형
Comments