Как управлять разделителями в PreferenceFragment?
Я начал использовать предпочтения в PreferenceFragment
. Вот что у меня есть:
![my_preferences]()
Я пытаюсь:
-
избавиться от разделителей между элементами. Я полагаю, это можно определить из стилей, но я не могу понять, как это сделать. Я попытался получить
предпочтение ListView
во время вызова
findViewById(android.R.id.list)
, как я где-то читал, но это
возвращает null.
-
установите новые разделители полной ширины прямо поверх заголовков, как показано здесь. Например, в этом случае я хочу полный делитель ширины чуть выше "Statistiche", но не выше "Generali", который находится поверх списка.
Единственный способ, который приходит мне на ум - установить делители в качестве поддельных предпочтений, например:
<Preference
android:layout="@layout/divider" //here I set width and a divider resource
/>
<PreferenceCategory ... />
Основная проблема здесь в том, что у моего PreferenceFragment
(или ActionBarActivity
it in) есть некоторая левая/правая прокладка, которая делает любой делитель, который я добавляю в preferences.xml не, покрывает весь ширина.
Итак, мой вопрос:
-
Как я могу избавиться от разделителей элементов по умолчанию, которые вы видите на изображении?
-
Как установить полные разделители ширины прямо над заголовками или как я могу избавиться от внутренних фрагментов/действий? Конечно, у моего макета активности нет (явного) дополнения.
Ответы
Ответ 1
Если бы полностью забыл об этом вопросе, теперь опубликует ответ, чтобы помочь другим. Я решил, перемещая мой код в методе onResume()
активности, в которой размещается мой PreferenceFragment
. Я думаю, что есть несколько других точек, в которых вы можете вспомнить ненулевой ListView
, используя findViewById(android.R.id.list)
.
public boolean mListStyled;
@Override
public void onResume() {
super.onResume();
if (!mListStyled) {
View rootView = getView();
if (rootView != null) {
ListView list = (ListView) rootView.findViewById(android.R.id.list);
list.setPadding(0, 0, 0, 0);
list.setDivider(null);
//any other styling call
mListStyled = true;
}
}
}
Вероятно, вы можете избавиться от проверки rootView
, но в то же время вы можете даже проверить на list != null
. В любом случае, я не сталкивался ни с каким NPE.
Итак, setDivider(null)
снимает разделители элементов. Мне удалось добавить разделители разделов, покрывающие всю ширину экрана:
- Удаление отступов от
list
;
- Добавление пользовательского предпочтения в мой XML:
п
<Preference
android:title="divider"
android:selectable="false"
android:layout="@layout/preference_divider"/>
Ответ 2
Добавьте этот код под PreferenceFragment
:
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// remove dividers
View rootView = getView();
ListView list = (ListView) rootView.findViewById(android.R.id.list);
list.setDivider(null);
}
Ответ 3
Хотя немного поздно, у меня такие же проблемы с разделителями на экране preff и нашел это решение:
Установите индивидуальный стиль для активности хостинга и добавьте стиль:
<item name="android:listDivider">@null</item>
Он фактически делает то же самое, что и устанавливать код через код, но вы сохраняете один findById, и я думаю, что он выглядит более четкими сетками прокрутки
Ответ 4
AndroidX делает это простым, но я бы хотел, чтобы это было лучше задокументировано.
В XML
Чтобы добавить/удалить разделители между настройками в XML, используйте следующие атрибуты:
<androidx.preference.PreferenceScreen
xmlns:app="http://schemas.android.com/apk/res-auto">
<Preference
...
app:allowDividerAbove="true/false"
app:allowDividerBelow="true/false"
... />
</androidx.preference.PreferenceScreen>
Обратите внимание, что разделитель будет отображаться только между двумя предпочтениями, если для верхнего делителя значение allowDividerBelow
установлено в значение true
а для нижнего разделителя значение allowDividerAbove
установлено в значение true
.
В коде
Вы также можете программно изменить/удалить разделители, используя следующие методы в onActivityCreated
вашего PreferenceFragmentCompat
:
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// To remove:
setDivider(null);
// To change:
setDivider(ContextCompat.getDrawable(getActivity(), R.drawable.your_drawable));
setDividerHeight(your_height);
}
Ответ 5
Для PreferenceFragmentCompat ListView не работает.
Но это работает как шарм:
<style name="PrefsTheme" parent="PreferenceThemeOverlay.v14.Material">
<item name="android:divider">@null</item>
<item name="android:dividerHeight">0dp</item>
</style>
Добавьте это в тему своего приложения:
<item name="preferenceTheme">@style/PrefsTheme</item>
Ответ 6
У меня была именно эта проблема, и я хотел разделить категории предпочтений, а не сами элементы. Я обнаружил, что принятое решение удовлетворило Вопрос 1, удалив разделители из элементов предпочтений, но не исправило вопрос 2 и не добавило разделители между категориями предпочтений.
Исправить ниже. В основном переопределите метод onCreateAdapter вашего PreferenceFragmentCompat и предоставьте ему собственный PreferenceGroupAdapter, у которого есть переопределенный метод onBindViewHolder, который использует позицию и все остальное, что вам нужно установить выше и ниже разрешений для каждого держателя представления. Разделитель будет нарисован, когда оба видоискателя разрешат разделитель между ними.
Вот мое исправление
public class SettingsFragment extends PreferenceFragmentCompat {
@Override
protected RecyclerView.Adapter onCreateAdapter(PreferenceScreen preferenceScreen) {
return new CustomPreferenceGroupAdapter(preferenceScreen);
}
static class CustomPreferenceGroupAdapter extends PreferenceGroupAdapter {
@SuppressLint("RestrictedApi")
public CustomPreferenceGroupAdapter(PreferenceGroup preferenceGroup) {
super(preferenceGroup);
}
@SuppressLint("RestrictedApi")
@Override
public void onBindViewHolder(PreferenceViewHolder holder, int position) {
super.onBindViewHolder(holder, position);
Preference currentPreference = getItem(position);
//For a preference category we want the divider shown above.
if(position != 0 && currentPreference instanceof PreferenceCategory) {
holder.setDividerAllowedAbove(true);
holder.setDividerAllowedBelow(false);
} else {
//For other dividers we do not want to show divider above
//but allow dividers below for CategoryPreference dividers.
holder.setDividerAllowedAbove(false);
holder.setDividerAllowedBelow(true);
}
}
}
Ответ 7
(Только для AndroidX)
Ответ Максима Иванова дошел до меня. Но чтобы удалить разделители только для определенных предпочтений, созданных в коде, мне пришлось сделать следующее:
val pref = object : Preference(activity) {
override fun onBindViewHolder(holder: PreferenceViewHolder) {
super.onBindViewHolder(holder)
// By default, preferences created in code show dividers
holder.setDividerAllowedAbove(false)
holder.setDividerAllowedBelow(false)
}
}
Ответ 8
если вы используете PreferenceFragment, вы можете использовать ListView. setDivider(null)
;
если вы используете PreferenceFragmentCompat, вы можете использовать PreferenceFragmentCompat. setDivider(Drawable divider)
или setDividerHeight(int height)
;
Ответ 9
Новое решение для нового API Android 24 и выше (25 декабря 2017 года).
Я нашел после многих способов использования stackoverflow, но не работал, или просто работает, но не работает в nestest PreferenceScreen
.
Фрист, вам нужно найти listview из текущего отображаемого фрагмента и удалить разделитель:
private fun removeDividerInCurrentFragment() {
[email protected](android.R.id.content)?.let {
it.view?.findViewById<ListView?>(android.R.id.list)?.let {
it.divider = null
it.dividerHeight = 0
}
}
}
Во-вторых, чтобы удалить разделитель при совершении фрагмента, вызовите метод выше (removeDividerInCurrentFragment
), чтобы удалить разделитель списка.
Конечно, если у вас nestest PreferenceScreen
. Зарегистрировать слушателя, когда фрагмент изменен в вашем PreferenceActivity
по протоколу FragmentManager.OnBackStackChangedListener
:
class YourPreferenceActivity : PreferenceActivity(), FragmentManager.OnBackStackChangedListener {
override fun onBackStackChanged() {
[email protected]()
}
}
Наконец, регистр backstack меняет прослушиватель по вызову fragmentManager.addOnBackStackChangedListener([email protected] YourPreferenceActivity)
в onCreate
. И удалите прослушиватель заметок назад с помощью вызова fragmentManager.removeOnBackStackChangedListener
в onDestroyed
.
Удачи!
Ответ 10
Вы можете переделать свой разделитель с помощью этой темы.
<style name="PreferenceFragment.Material">
<item name="android:divider">@drawable/preference_list_divider_material</item>
</style>