Android preference fragment compat example

The dependencies

implementation 'com.android.support:preference-v7:28.0.0-alpha3'
implementation 'com.android.support:preference-v14:28.0.0-alpha3'

The preference xml file that defines the setting ui. xml/pref_settings.xml, this will be used in the PreferenceFragmentCompat.



    

        

        

    

    
        

        
            
        

    


SettingsFragment.kt, it extends from the PreferenceFragmentCompat. This is where the above preference xml is initialized, and binds the ui with the name pair value stored in shared preference, as well as listening to the preference changes and act accordingly.

import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.preference.ListPreference
import android.preference.PreferenceManager
import android.support.v7.preference.Preference
import android.support.v7.preference.PreferenceFragmentCompat
import android.view.View

class SettingsFragment: PreferenceFragmentCompat(), Preference.OnPreferenceChangeListener {

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        // Hide the divider
        setDivider(ColorDrawable(Color.TRANSPARENT))
        setDividerHeight(0)
    }

    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
        // Load the preferences from an XML resource
        addPreferencesFromResource(R.xml.pref_settings)

        bindPreferenceSummaryToValue(findPreference(getString(R.string.pref_key_zipcode)))
        bindPreferenceSummaryToValue(findPreference(getString(R.string.pref_key_unit)))

    }

    private fun bindPreferenceSummaryToValue(preference: Preference) {
        preference.onPreferenceChangeListener = this

        onPreferenceChange(preference,
                PreferenceManager
                        .getDefaultSharedPreferences(preference.context)
                        .getString(preference.key, ""))
    }


    override fun onPreferenceChange(preference: Preference?, value: Any?): Boolean {
        val stringValue = value.toString()

        if (preference is ListPreference) {
            val listPreference = preference
            val prefIndex = listPreference.findIndexOfValue(stringValue)
            if (prefIndex >= 0) {
                preference.setSummary(listPreference.entries[prefIndex])
            }
        } else {
            preference?.summary = stringValue
        }
        return true
    }

    override fun onPreferenceTreeClick(preference: Preference): Boolean {
        return when (preference.key) {
            getString(R.string.pref_key_allow_notification) -> {
                true
            }
            getString(R.string.pref_key_zipcode) -> {
                true
            }
            getString(R.string.pref_key_unit) -> {
                true
            }
            else -> {
                super.onPreferenceTreeClick(preference)
            }
        }
    }

}

The SettingsActivity, which houses the above settings fragment.

import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_settings.*

class SettingsActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_settings)
        setSupportActionBar(app_toolbar)

        supportActionBar?.setDisplayHomeAsUpEnabled(true)
        supportActionBar?.setDisplayShowHomeEnabled(true)

        supportFragmentManager.beginTransaction()
                .replace(R.id.content, SettingsFragment())
                .commit()
    }
}

The theme style for the SettingsActivity, it has to extend PreferenceThemeOverlay or the setting activity will crash.


Apply the above preference theme in the manifest file.



The MainActivity

class MainActivity : AppCompatActivity() {

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

        setSupportActionBar(app_toolbar)
    }

    override fun onResume() {
        super.onResume()

        val sharedPref = PreferenceManager.getDefaultSharedPreferences(this)
        et_allow_notification.setText(sharedPref.getBoolean(getString(R.string.pref_key_allow_notification), false).toString())
        et_zipcode.setText(sharedPref.getString(getString(R.string.pref_key_zipcode), ""))
        et_unit.setText(sharedPref.getString(getString(R.string.pref_key_unit), ""))
    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        // Inflate the menu; this adds items to the action bar if it is present.
        menuInflater.inflate(R.menu.menu_setting, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.

        return when (item.itemId) {
            R.id.action_settings -> {
                startActivity(Intent(this, SettingsActivity::class.java))
                true
            }
            else -> super.onOptionsItemSelected(item)
        }
    }
}

The layout file for the settings activity, activity_settings.xml




    
    

    


The layout file for the MainActivity, activity_main.xml




    
    


    
        
    

    
        
    

    
        
    

String resources, strings.xml


    Android Preference Fragment

    Settings
    android.support.design.widget.AppBarLayout$ScrollingViewBehavior

    pref_allow_notification
    pref_key_zipcode
    pref_key_unit

    
        Celsius
        Fahrenheit
    

    
        Celsius
        Fahrenheit
    



menu/menu_setting.xml, this is the menu on the top right corner in the main screen.


    

Complete example in Github

Search within Codexpedia

Custom Search

Search the entire web

Custom Search