How do I programmatically add EditTextPreferences to my PreferenceFragment?

codingjeremy picture codingjeremy · Jun 22, 2013 · Viewed 8.4k times · Source

I am new to Android, so I need a little guidance on how to programmatically add EditTextPreference objects to my PreferenceFragment.

I am pulling in a list of values from a web service. I have saved them successfully to my SharedPreferences, and I use them to generate URLs (path portion).

I would like the users of my app to be able to edit these values, but after lots of searching on Google, it isn't clear to me how to programmatically add EditTextPreference objects to my PreferenceFragment.

Please note, my PreferenceFragment is working fine for the SharedPreferences values I hard code as names into the preference xml file (PreferenceScreen). I also know how to get my SharedPreferences, so don't worry about having to explain that portion to me.

I use addPreferencesFromResource in onCreate of my PreferenceFragment. Should I add them in the onCreateView? I was thinking I could get the PreferenceCategory and add them there? But again, I am not sure how to do that. I would really be grateful for the help!

// Code

PrefsFragment.java:
package com.example.lorddoineedhelp;

import android.os.Bundle;
import android.preference.PreferenceFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class PrefsFragment extends PreferenceFragment {
  @Override
  public void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   addPreferencesFromResource(R.xml.preferences); 
  }

  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View v = super.onCreateView(inflater, container, savedInstanceState); 
    // I am guessing I need to do something here?
    return v;
  }
}

XML File for PreferenceFragment:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
  <!-- Hard coded values -->
  <PreferenceCategory
          android:title="General">
    <CheckBoxPreference
            android:key="debug"
            android:title="Debug"
            android:summary="Enable Debug" />
  </PreferenceCategory>
  <PreferenceCategory android:title="Address">
    <EditTextPreference 
        android:key="ipAddress"
        android:title="IP Address"
        android:summary="IP Address used for Image pings"
    />
    <EditTextPreference
          android:key="port"
          android:title="Port"
          android:summary="Port used for Image pings" />
  </PreferenceCategory>

  <!-- Where I want to add the values from my web service -->

   <PreferenceCategory 
       android:title="Paths"
       android:key="urlPaths">
  </PreferenceCategory>
</PreferenceScreen>

Answer

Paul Smith Racing picture Paul Smith Racing · Apr 22, 2015

You can add preferences, e.g. EditTextPreference, CheckBox, etc, programmatically in the "onCreate" method of the PreferenceFragment.

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Load "dummy" (empty) preferences from an XML resource
    addPreferencesFromResource(R.xml.preferences_channelconfig);

    PreferenceScreen screen = this.getPreferenceScreen(); // "null". See onViewCreated.

    // Create the Preferences Manually - so that the key can be set programatically.
    PreferenceCategory category = new PreferenceCategory(screen.getContext());
    category.setTitle("Channel Configuration");
    screen.addPreference(category);

    CheckBoxPreference checkBoxPref = new CheckBoxPreference(screen.getContext());
    checkBoxPref.setKey(channelConfig.getName() + "_ENABLED");
    checkBoxPref.setTitle(channelConfig.getShortname() + "Enabled");
    checkBoxPref.setSummary(channelConfig.getDescription());
    checkBoxPref.setChecked(channelConfig.isEnabled());

    category.addPreference(checkBoxPref);
}

The crucial step is the addPreferencesFromResource(...), with a dummy xml to attach an empty PreferenceScreen to the fragment. Without this, there is no "top-level Preference that is the root of a Preference hierarchy", thus this.getPreferenceScreen() returns Null.

The XML I used was just:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    android:orderingFromXml="true">

</PreferenceScreen>

Hope that helps someone.