Пользовательский ListPreference в AndroidX

Я настроил страницу настроек приложения Android, использую API 21 или 26. Я добавил класс Java CustomListPreference, унаследованный от ListPreference, и интегрировал его в SettingActivity.

Но я повторно указал, что система не работает, так как SettingActivity имеет фрагмент настройки, унаследованный от androidx.preference.PreferenceFragmentCompat, а пакеты, используемые для настройки действия, следующие:

  • androidx.preference.Preference
  • androidx.preference.ListPreference
  • androidx.preference.PreferenceFragmentCompat

Если я использую пакеты android.preference.Preference и android.preference.ListPreference для моего Custom ListPreference, весь мой код перестает работать, когда Android создает объекты для действия настройки. Он аварийно завершает работу сразу после пользовательского конструктора ListPreference с ошибкой "Error inflating class com.signatact.doorbell.dialog.preference.AppListPreference". Копаясь в деталях, я нашел причину сбоя, поскольку последним шагом для создания нового объекта для настройки действия является приведение к androidx.preference.Preference:

из PreferenceInflater.java:

import androidx.preference;
...
return (Preference) constructor.newInstance(args); // line 242

Понятно, система дает сбой с приведением между android.preference.Preference и androidx.preference.Preference.

Однако, если я перенесу свою пользовательскую реализацию файла ListPreference в androidx, почти все методы, которые я использовал ранее для настройки, будут недоступны, здесь приведен список методов, которые недоступны, где я помещаю свою пользовательскую логику:

// Ошибки: методы не переопределяют методы своего суперкласса

@Override
    protected void onPrepareDialogBuilder(AlertDialog.Builder builder)
...
@Override
    protected void onDialogClosed(boolean positiveResult)

Похоже, Google резко изменил свой API, кто-нибудь может подсказать, как в AndroidX можно настроить ListPreference? В общем, мне нужны стандартные вещи настройки следующим образом:

  • В строке у меня есть пользовательский набор элементов управления (3 из них - 2 текстовых поля и 1 флажок) - я создаю собственный макет для каждой строки в onPrepareDialogBuilder с помощью моего пользовательского ArrayAdapter для списка
  • Мне нужно динамически обновлять значения CustomListPreference. Я заполняю эти значения в onResume в SettingActivity
  • Мне нужно получить обратный вызов, когда список нажат и выбрано новое значение

Я нашел здесь только одно практическое руководство для своего случая: Как изменить внешний вид диалогового окна ListPreference, но это ограниченный и короткий. Я проанализировал API AndroidX, и похоже, что мне нужно больше времени, чтобы найти решение, и поэтому любая помощь/идея приветствуется...

Спасибо, Влад.


person Liatoss    schedule 15.03.2020    source источник
comment
Вы нашли решение для этого?   -  person Shadow    schedule 27.10.2020


Ответы (1)


Просто переопределите функцию onClick(), чтобы вывести AlertDialog с пользовательским макетом. Не забудьте вызвать setValue(), когда что-либо выбрано в диалоговом окне.

public class ColorPreference extends ListPreference {
    
    private CharSequence[] mEntries;
    private CharSequence[] mEntryValues;
    private String mValue;
    private String mSummary;
    
    private AlertDialog mDialog;

    public ColorPreference(Context context) {
        this(context, null);
    }

    public ColorPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
        setDefaultValue(Options.DEFAULT_PRIMARY_COLOR_STRING);
    }


    @Override
    protected void onClick() {
        mEntries = getEntries();
        mEntryValues = getEntryValues();
        mSummary = getSummary().toString();
        mValue = getValue();
        
        mClickedDialogEntryIndex = findIndexOfValue(mValue);

        AlertDialog.Builder builder = new AlertDialog.Builder(getContext());

        builder.setSingleChoiceItems(new ColorAdapter(getContext(), R.layout.pref_color_item),mClickedDialogEntryIndex,null);
             
        mDialog = builder.create();

        mDialog.show();
    }

}
person KevinChung    schedule 16.06.2021