以编程方式在PreferenceScreen中向特定位置添加首选项

时间:2017-04-04 21:42:09

标签: android android-preferences

我以编程方式填充部分首选项。这很好用。不幸的是,当用户更改某些偏好时,必须添加新的首选项(考虑“添加新警报' - 首选项”)。当我使用PreferenceCategorie时,这也可以正常工作(因为在一个这样的结尾处添加了新的,所以myPreferenceCategory.addPreference(newPreference)就可以了。)但是,如何以编程方式将Preference添加到任何特定位置(而不仅仅是常用类别的结尾/ prefScreen?

not so invisible category

我尝试使用某种"隐形" PreferenceCategory,将android:layout="my_custom_invis_layout"设置为

<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"/>

不幸的是,这些填充和边距似乎对空类别所占的最小空间没有影响(但是这样做是正值,这是 - 原因 - 没有帮助)。

我也尝试通过

取消布局
<PreferenceCategory
    android:layout="@null">

但这只会扩大该类别对其他偏好所具有的空间。

不幸的是,到目前为止,SO并没有帮助我。如果有人能指出我喜欢的东西,那么我会非常高兴。添加偏好A低于偏好B&#34;或者如何使一个类别完全没有空间(因为这也可以解决我的问题)。

2 个答案:

答案 0 :(得分:2)

我看到这个问题已经很老了,但由于我遇到了类似的问题并设法解决了这个问题,我认为无论如何都不会发布任何伤害。 我解决这个问题的方法是从一开始就在xml中添加Preference(在我的情况下是需要在其他类别中的特定位置添加的类别),如果不需要则以编程方式将其删除。当之后(以编程方式)将其放回时,它在移除之前出现在相同的位置。没有尝试过你的特定情况(单个偏好需要进入一个类别中的特定位置),但我敢打赌它的工作方式相同。

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);
    }
}

答案 1 :(得分:2)

好的,我尝试过使用Preferences#setOrder(int)的其他方法。 (我在那里留下了之前的答案,导致一些用例可能是更容易解决的问题。)这个更适合您的需求吗?

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++;
    }
}