johboh
johboh

Reputation: 1023

Refresh a ListPreference

I have a ListPreference which I populate dynamically when clicking on the list to display it. The population works fine, but the values I populate is not displayed until the next time i click to open the list, but instead the values from the xml-file is displayed the first time. It feels like the list has already been populated before the onPreferenceClick is called. How can I refresh the list probably? I want to populate the list before every click in the list.

     /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  addPreferencesFromResource(R.xml.preferences);

  // Get preferences.
  prefs = PreferenceManager.getDefaultSharedPreferences(this);
  screen = getPreferenceScreen();

  // Install on-click listener for calendars.
  screen.findPreference("googleCalendars").setOnPreferenceClickListener(onSelectCalendarsClick);
 }

 /**
  * We had a click on select calendars.
  */
 public OnPreferenceClickListener onSelectCalendarsClick = new OnPreferenceClickListener() {
  public boolean onPreferenceClick(Preference pref) {

   final String username;
   final String password;
   final String list;

   if (pref == findPreference("googleCalendars")) {
    username = prefs.getString("googleUsername", "");
    password = prefs.getString("googlePassword", "");
    list = "googleCalendars";
   }
   else {
    Log.d(TAG, "onSelectCalendarsClick.run(),unknown list clicked: " + pref.getTitle());
    return false;
   }

   // Show process dialog while updating.
      final ProgressDialog dialog = ProgressDialog.show(Preferences.this, "", "Fetching calendars, please wait...", true);
      // Show dialog, non cancelable.
      dialog.setCancelable(false);
       dialog.show();

   // Create new updater thread.
   new Thread(){
    public void run() {
     Log.d(TAG, "onSelectCalendarsClick.run(), new thread. Fetching calendars...");
     // Get calendars
     // Create API.
     CalendarApi calendarApi = new CalendarApi(prefs.getBoolean("debugFakeCalendar", false));
     GetCalendarsResponse response = calendarApi.GetCalendars(username, password);
     Log.d(TAG, "onSelectCalendarsClick.run(), new thread. Done!");
     // Create new message and send it.
     Message msg = new Message();
     Bundle bundle = new Bundle();
     bundle.putString("list", list);
     msg.setData(bundle);
     msg.obj = response;
     getCalendarsHandler.sendMessage(msg);
     // cancel dialog.
     dialog.cancel();
    }
   }.start();

   return false;
  }

 };

 /**
  * Handler for processing response from getCalendars.
  */
    Handler getCalendarsHandler = new Handler() {
      @Override
      public void handleMessage(Message msg) {
        super.handleMessage(msg);


        // We have a new message.
        GetCalendarsResponse response = (GetCalendarsResponse)msg.obj;
        Bundle bundle = msg.getData();

        // Null?
        if (response == null || response.calendars == null) {
          Log.d(TAG, "getCalendarsHandler.handleMessage(): response is null.");
          return;
        }

         // Fetch.
        ListPreferenceMultiSelect list = (ListPreferenceMultiSelect)screen.findPreference(bundle.getString("list"));
        if (list != null) {
          // Ok response.
          list.setEntries(response.getEntries());
          list.setEntryValues(response.getEntryValues());
        }

        // Display list preference.
        list.getDialog().show(); 
      }
    };
}

Upvotes: 1

Views: 2969

Answers (2)

n_slash_a
n_slash_a

Reputation: 1

I realize this question is about 10 years old, but I had the same problem and there was no answer yet, and I figure more people will have this issue in the future. Also, /u/radhashankark is correct, the problem is that the onPreferenceClick function has already populated the ListPreference by the time setEntries is called, so any changes do you are no reflected in the list.

The solution to this is that you need to create a local list preference class.

public class YourClassListPreference extends android.preference.ListPreference

Then fill in all the associated constructors, getOnDialogClickListener (not sure if needed), setOnDialogClickListener (also not sure if needed), getOnPreferenceClickListener, setOnPreferenceClickListener, and most importantly onClick.

Now for the important part, in the onClick function, first call your mOnPreferenceClickListener.onPreferenceClick(this), and then call super.onClick(). This will let you populate the ListPreference before it "gets called".

You will also need to update ListPreference to YourClassListPreference in all the declarations, casts, and xml files where this is used. I also found in the xml files, you need to use the full path (not just YourClassListPreference, but com.android.settings.YourClassListPreference or however your build is setup).

Upvotes: 0

radhashankark
radhashankark

Reputation: 155

The documentation for setEntries states that the settings will be shown in the subsequent dialogs.

Android populates the ListPreference as soon as OnClickPreference is fired, and anything you do after that will be shown in the subsequent dialogs.

You might want to populate it beforehand than refresh it after it is shown. Best way to populate it beforehand is to populate the ListPreference in onCreate, and let it sit there to be shown.

Hope this helps

Upvotes: 1

Related Questions