본문 바로가기
Android App/Kotlin

파일 입출력-내부 저장소 사용(SharedPreferences, 설정화면 만들고 설정 값 사용하기)

by AppJinny 2022. 11. 20.

*파일 입출력-내부 저장소 사용(SharedPreferences, 설정화면 만들고 설정 값 사용하기)

-안드로이드는 SharedPreferences API 제공하여 레이아웃 파일을 이용해 화면을 구성하지 않아도 설정 화면을 만들 수 있음

-설정화면 만들기 : AndroidX Preference 라이브러리의 PreferenceFragment 사용(안드로이드 10부터)

 

 

*설정화면 만들고 설정 사용하기

-build.gradle

--dependencies{} 에 androidx.Preference 의존성 추가

--스트럭처에서 의존성을 검색하여 추가하는 방법 : https://heeyjinny.tistory.com/85

//추가된 AndroidX Preference 라이브러리
//implementation 'androidx.preference:preference:1.2.0'

//최신 버전의 라이브러리를 추가하였으나 정상작동하지 않아 버전을 낮춤...
implementation 'androidx.preference:preference:1.1.1'

 

-MainActivity.kt

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

        //1
        //AndroidX Preference 사용을 위해서는 라이브러리 설치가 필요함
        //특정 라이브러리가 있어야만 프로그램이 동작하며 해당 라이브러리에 의존성이 있다고 함
        //build.gradle에 androidx.preference 의존성(dependency) 추가

        //2
        //XML로 설정 화면에서 사용할 화면 구조를 정의해두면
        //안드로이드가 정의된 XML의 구조를 분석해 화면을 그려줌
        //설정 화면에서 사용할 화면 구조 정의 하기

        //2-1
        //리소스 디렉터리 res폴더 안에 xml 디렉터리를 생성하고 그 안에 preferences.xml 생성하기
        //사용할 설정화면 구조 정의 시 생성하는 xml파일의 Root element는 PreferenceScreen 정의
        //디렉터리 res - 우클릭 - New - Android Resource FIle

        //File name : preferences
        //Resource Type : XML
        //Root element : PreferenceScreen (위 타입 지정하면 자동으로...)
        //Source set : main (위 타입 지정하면 자동으로...)
        //Directory name : xml (위 타입 지정하면 자동으로...)

        //생성한 preferences.xml 수정성


        //FIN
        //설정값 사용
        //XML 레이아웃을 조금 추가하면 쉽게 Preference 화면을 만들 수 있음

        //각각의 Preference를 설정하면 자동으로 옵션이 저장되고 저장된 옵션을 읽으려면 key 이용
        //PreferenceManager에서 getDefaultSharedPreferences로 SharedPreference 가져와 사용

        //저장된 데이터가 boolean인 경우 getBoolean(key, default)
        //초기값이 없는 경우 default로 설정한 것을 가져오게 됨
        //문자열의 경우 getString을 사용합니다. Int와 Long, Float도 모두 동일한 방식 사용

        //PreferenceManager를 통해 SharedPreference 가져와 shared에 저장
        val shared = PreferenceManager.getDefaultSharedPreferences(this)

        //키 값과 기본값 지정하여 현재 설정된 데이터 가져오기
        val checkboxValue = shared.getBoolean("key_add_shortcut",false)
        val switchValue = shared.getBoolean("key_switch_on", false)
        val name = shared.getString("key_edit_nam", "이름을 입력하세요")
        val selected = shared.getString("key_set_item", "목록을 선택하세요")

    }
}

 

-preferences.xml 

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

<!--  <PreferenceCategory> 태그 사용하여 기능, 옵션 2개 카테고리 생성 -->
<!--  카테고리는 주로 입력 필드의 그룹명을 출력하는 용도로 사용됨  -->

<!--  1  -->
<!--  <PreferenceCategory 설정사항 생성위치 ></PreferenceCategory> -->
<!--  설정사항 생성위치에 타이틀과 아이콘 할당공간 입력  -->

<!--  카테고리 속성  -->
<!--  app: iconSpaceReserved=false는 아이콘을 위해 할당된 공간을 없애라는 의미  -->
<!-- 이 속성을 추가하지 않으면 아이콘 공간이 남아있어 왼쪽으로 패딩이 있는 것처럼 보임 -->
<!--  android: 가 아닌 app: 에 설정해야함 주의!  -->

<!--  2  -->
<!--  카테고리 안에 실제 입력 필드 구성  -->

<!--  입력 필드들의 공통 속성  -->
<!--  key : 현재 어떤 값이 저장되어있는지(on/off 등) key를 통해 값을 읽을 수 있음-->
<!--  icon : 보여주는 아이콘의 위치, 지정하지 않으면 빈 칸이 생길 수 있음  -->
<!--  defaultValue : 초기 값의 on/off  -->

    <PreferenceCategory
        android:title="기능 설정"
        app:iconSpaceReserved="false">

        <!--  체크박스 생성  -->
        <CheckBoxPreference
            android:key="key_add_shortcut"
            android:title="바로가기 아이콘"
            android:icon="@mipmap/ic_launcher"
            android:defaultValue="true"/>

        <!--  스위치 생성  -->
        <SwitchPreference
            android:key="key_switch_on"
            android:title="화면 켜짐"
            android:icon="@mipmap/ic_launcher"
            android:defaultValue="false"/>

    </PreferenceCategory>

    <PreferenceCategory
        android:title="옵션 설정"
        app:iconSpaceReserved="false">

        <!--  텍스트 입력 할 수 있는 Preference  -->
        <EditTextPreference
            android:key="key_edit_name"
            android:title="이름"
            android:summary="이름을 입력하세요"
            android:dialogTitle="이름 입력"
            app:iconSpaceReserved="false"/>

        <!--  ListPreference: 목록 중 1를 선택할 수 있는 Preference  -->
        <!--  XML로 정의된 목록 데이터가 필요하여 일단 이름만 먼저 정의하여 경로 기입  -->
        <ListPreference
            android:key="key_set_item"
            android:title="목록 선택형"
            android:summary="목록을 선택하세요"
            android:entries="@array/action_list"
            android:entryValues="@array/action_values"
            android:dialogTitle="목록 선택 제목"
            app:iconSpaceReserved="false"/>

        <!--  PreferenceScreen: 다른 화면으로 넘어가는 Preference  -->
        <!--  intent 인자를 주어 브라우저가 android.com을 열도록 설정함 (링크비슷)  -->
        <PreferenceScreen
            android:title="Android 홈페이지 연결"
            android:summary="사이트로 연결 합니다"
            app:iconSpaceReserved="false">

            <intent android:action="android.intent.action.VIEW"
                android:data="http://www.android.com"/>

        </PreferenceScreen>

    </PreferenceCategory>

<!--  이어서 ListPreference에서 먼저 정의한 목록데이터 파일(array) 생성  -->
<!--  res - values 디렉터리 우클릭 - New - Values Resource File  -->
<!--  File name(파일명) : array  -->
<!--  array.xml 파일 생성  -->

</PreferenceScreen>

 

-array.xml

<!-- preferences.xml의 <ListPreference/> 가 참조하는 목록 데이터 -->
<resources>
    <!-- 각 태그의 name에 해당하는 부분은 ListPreference의 entries, entryValue로 사용됨   -->
    <string-array name="action_list">
        <item>action 1</item>
        <item>action 2</item>
        <item>action 3</item>
        <item>action 4</item>
    </string-array>

    <string-array name="action_values">
        <item>values 1</item>
        <item>values 2</item>
        <item>values 3</item>
        <item>values 4</item>
    </string-array>

<!--  이제 preferences.xml 을 가지고 있는 SettingFragment 클래스 생성  -->
<!--  java 디렉터리 밑 패키지명 우클릭 - New - Kotlin Class/File - SettingFragment 클래스 생성  -->

</resources>

 

-SettingFragment.kt

//PreferenceFragmentCompat 추상클래스를 상속받음
class SettingFragment: PreferenceFragmentCompat() {

    //onCreatePreferences() 메서드 오버라이드
    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {

        //addpreferencesFromResource 호출하고
        //PreferenceScreen이 정의된 preference.xml 파일의 경로를 파라미터로 전달하면
        //설정 항목의 뷰가 자동으로 생성됨
        addPreferencesFromResource(R.xml.preferences)

    }

    //activity_main.xml 에 <fragment/> 화면을 추가하여 SettingFragment와 연결

}

 

-activity_main.xml

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">


<!--  SettingFragment 추가  -->
    <fragment
        android:id="@+id/fragmentContainerView"
        android:name="com.heeyjinny.sharedpreferencessettingview.SettingFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>


<!--  설정화면 에뮬레이터 오류로 인해 수정한 것...
라이브러리 업그레이드...
그레이들 프래그먼트 라이브러리 버전 다운 1.2.0 -> 1.1.1
경고메시지에 따라  targetSdk , compileSdk 를 32 -> 33 으로
여전히 액티비티.xml 의 미리보기 뷰는 안 보이지만...
에뮬레이터 실행 시 뷰가 잘 보이고 다른 사이트로 화면 넘기는 것도 잘 동작함...

해결방법 알아볼 것...
-->

<!--  설정 값 사용을 위해 MainActivity.kt 코드 작성  -->

</androidx.constraintlayout.widget.ConstraintLayout>

 

-결과

 

 

 

 

-참고

https://codechacha.com/ko/android-preference/

 

 


이 포스팅에 작성한 내용은 고돈호, ⌜이것이 안드로이드다⌟, 한빛미디어(주), 2022 에서 발췌하였습니다.