Reputation: 283
I am populating parts of my preferences programmatically. This works fine. Unfortunately new preferences there has to be added, when the user changes some preferences (think of an 'add a new alarm'-preference). This works fine as well, when I use PreferenceCategorie
s (because the new ones are added at the end of one such, so myPreferenceCategory.addPreference(newPreference)
does the trick). But what can I do to programmatically add a Preference to any specific place (not just the end of usual categories/the prefScreen??
I tried to use some kind of "invisible" PreferenceCategory, by setting android:layout="my_custom_invis_layout"
with
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/my_custom_invis_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="0dp"
android:paddingTop="0dp"
android:layout_marginTop="0dp"
android:layout_marginBottom="0dp"/>
Unfortunately those padding and margin does not seem to have an impact on the minimum space the empty category take (but do so with positive values, which is - of cause - of no help).
I tried as well to nullify the layout by
<PreferenceCategory
android:layout="@null">
but this just enlarges the space the category takes to those the other preferences have.
Unfortunately SO did not help me on this so far. I would be very happy if anyone can point me to something like "add a preference A below preference B" or on how to make a category taking no space at all (as this would resolve my problem as well).
Upvotes: 5
Views: 2488
Reputation: 3068
You can sort preferences alphabetically by title.
To do so you need to set isOrderingAsAdded
to false for the PreferenceGroup
your are using, category or screen. Thus when you add a new preference it just takes its place.
Upvotes: 0
Reputation: 1373
Ok, I've tried that other approach with Preferences#setOrder(int). (I left the previous answer there, cause for some use cases it might be the easier solution.) Does this one better suit your needs?
public class PreferencesFragment extends PreferenceFragmentCompat {
private SharedPreferences mSharedPreferences;
PreferenceCategory mMyPreferenceCategory;
// ArrayList to keep track of the currently added Preferences
ArrayList<Preference> mPreferenceList = new ArrayList<>();
// this counter only serves for name-giving of the added
// Preferences in this example
int mCounter = 0;
@Override
public void onCreatePreferences(@Nullable Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.preferences);
mMyPreferenceCategory = (PreferenceCategory) findPreference("preferenceCategoryKey");
addPreference(null);
}
// adds a Preference that is inserted on the position of the
// clicked Preference, moving the clicked Preference - and all
// Preferences after - one position down
private void addPreference(Preference pref) {
int order = 0;
if (pref != null) {
order = pref.getOrder();
}
for (Preference preference : mPreferenceList) {
int oldOrder = preference.getOrder();
if (oldOrder >= order) {
preference.setOrder(oldOrder+1);
}
}
Preference newPreference = new Preference(getContext());
newPreference.setTitle("Preference " + mCounter);
newPreference.setOrder(order);
newPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
addPreference(preference);
return false;
}
});
mMyPreferenceCategory.addPreference(newPreference);
mPreferenceList.add(newPreference);
mCounter++;
}
}
Upvotes: 3
Reputation: 1373
I see this question is quite old, but since I was facing a similar problem and managed to solved it, I figured there would be no harm done by posting anyway. The way I solved this is by adding the Preference (in my case a category that needed to be added in a particular spot amongst the other categories) in xml from the start, removing it programmatically if not yet needed. When putting it back (programmatically) afterwards, it appears at the same position it was before removing it. Haven't tried your particular case (with single Preferences needing to go in a particular spot within a category), but I bet it works the same way.
public class PreferencesFragment extends PreferenceFragmentCompat {
private SharedPreferences mSharedPreferences;
private PreferenceCategory mPreferenceCategory;
@Override
public void onCreatePreferences(@Nullable Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.preferences);
mPreferenceCategory = (PreferenceCategory) findPreference("preferenceCategoryKey");
if (preferenceNotRequiredYet) {
removePreferenceCategory();
}
// an I have a SharedPreferenceListener attached that calls
// addPreferenceCategory when I need to add it back
}
private void removePreferenceCategory() {
PreferenceScreen parentScreen = (PreferenceScreen) findPreference("parent_screen_key");
parentScreen.removePreference(mPreferenceCategory);
}
private void addPreferenceCategory() {
PreferenceScreen parentScreen = (PreferenceScreen) findPreference("parent_screen_key");
parentScreen.addPreference(mPreferenceCategory);
}
}
Upvotes: 5