以编程方式将首选项添加到 PreferenceScreen 中的特定位置
Add preferences to specific places in PreferenceScreen programmatically
我正在以编程方式填充我的部分偏好设置。这很好用。不幸的是,当用户更改某些偏好(想想 'add a new alarm' 偏好)时,必须添加新的偏好。这也很好,当我使用 PreferenceCategorie
s 时(因为新的是在这样的末尾添加的,所以 myPreferenceCategory.addPreference(newPreference)
可以解决问题)。但是我该怎么做才能以编程方式将首选项添加到任何特定位置(不仅仅是通常 categories/the prefScreen 的末尾??
我尝试使用某种 "invisible" 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"/>
不幸的是,这些填充和边距似乎对空类别的最小值 space 没有影响(但使用正值这样做,这 - 原因 - 没有帮助)。
我也尝试通过
取消布局
<PreferenceCategory
android:layout="@null">
但这只是扩大了 space 类别对其他偏好所具有的类别的影响。
不幸的是,到目前为止,SO 并没有帮助我解决这个问题。如果有人能指出 "add a preference A below preference B" 之类的内容或如何创建一个完全不使用 space 的类别(因为这也可以解决我的问题),我将非常高兴。
我看到这个问题已经很老了,但是由于我遇到了类似的问题并设法解决了它,所以我认为无论如何发帖都没有什么坏处。
我解决这个问题的方法是从一开始就在 xml 中添加首选项(在我的例子中是需要在其他类别中的特定位置添加的类别),如果还不需要,则以编程方式将其删除。之后(以编程方式)将其放回原位时,它会出现在删除之前的相同位置。还没有尝试过您的特定情况(单个首选项需要进入类别中的特定位置),但我敢打赌它的工作方式相同。
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);
}
}
好的,我已经尝试过使用 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++;
}
}
我正在以编程方式填充我的部分偏好设置。这很好用。不幸的是,当用户更改某些偏好(想想 'add a new alarm' 偏好)时,必须添加新的偏好。这也很好,当我使用 PreferenceCategorie
s 时(因为新的是在这样的末尾添加的,所以 myPreferenceCategory.addPreference(newPreference)
可以解决问题)。但是我该怎么做才能以编程方式将首选项添加到任何特定位置(不仅仅是通常 categories/the prefScreen 的末尾??
我尝试使用某种 "invisible" 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"/>
不幸的是,这些填充和边距似乎对空类别的最小值 space 没有影响(但使用正值这样做,这 - 原因 - 没有帮助)。
我也尝试通过
取消布局<PreferenceCategory
android:layout="@null">
但这只是扩大了 space 类别对其他偏好所具有的类别的影响。
不幸的是,到目前为止,SO 并没有帮助我解决这个问题。如果有人能指出 "add a preference A below preference B" 之类的内容或如何创建一个完全不使用 space 的类别(因为这也可以解决我的问题),我将非常高兴。
我看到这个问题已经很老了,但是由于我遇到了类似的问题并设法解决了它,所以我认为无论如何发帖都没有什么坏处。 我解决这个问题的方法是从一开始就在 xml 中添加首选项(在我的例子中是需要在其他类别中的特定位置添加的类别),如果还不需要,则以编程方式将其删除。之后(以编程方式)将其放回原位时,它会出现在删除之前的相同位置。还没有尝试过您的特定情况(单个首选项需要进入类别中的特定位置),但我敢打赌它的工作方式相同。
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);
}
}
好的,我已经尝试过使用 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++;
}
}