Подтвердить что ты не робот

Как открыть или имитировать щелчок на андроиде Предпочтение, созданное с помощью XML, программно?

У меня есть приложение Android с настройками, объявленными в XML, загруженные с помощью addPreferencesFromResource. Пользователь может открыть настройки, щелкнуть по каждому элементу и отредактировать их, все работает.

Одно из моих предпочтений:

        <ListPreference android:key="abc"
            android:title="@string/abc"
            android:summary="@string/cde"
            android:persistent="true"/>

Как я могу автоматически показать диалог настроек пользователю (без необходимости перехода пользователя на экран настроек и нажмите на него?).

Я пробовал ( (android.preference.DialogPreference) prefMgr.findPreference( "abc" )).showDialog(null), но говорит, что это защищенный метод...? Вызывается из моего основного действия (это PreferenceActivity), поэтому он явно не может работать. Но как еще?

ИЗМЕНИТЬ

Я только что нашел два потока (1 и 2) с идеей использовать findViewById для доступа к предпочтениям, но без успеха. Он всегда возвращает null (для меня тоже).

Похоже, что нет никакой возможности сделать это из кода.

4b9b3361

Ответ 1

Вы могли бы расширить ListPreference, чтобы создать свое диалоговое окно, а затем включили свой собственный общедоступный метод, который вызывает защищенный метод showDialog ListPreference. Что-то вроде:

public void show()
{
    showDialog(null);
}

Таким образом, вы не столкнетесь с проблемой getOrder(), которая не работает, когда есть PreferenceGroups, поскольку несколько человек указали в комментариях ваш ответ.

Это можно сделать с помощью любых типов предпочтений, которые имеют защищенный метод showDialog.

Ответ 2

См. новый принятый ответ для более чистого подхода! Это работало, но не совсем чистый способ сделать это.


Черт возьми, он получил меня несколько часов, но он, наконец, работает.

Решение - это недокументированный вызов public void onItemClick (...). Это требует нескольких аргументов, и, как указано этим вопросом, его можно использовать для имитации щелчка в соответствии с индексом элемента, который вы хотите вызвать.

Моя проблема заключалась в том, что элемент, который я хочу вызвать, глубоко вложен в XML-структуру. Но решение очень просто: добавьте key в PreferenceScreen элемент, который вы хотите открыть, в:

<PreferenceScreen
    android:key="pref_key"
    ....
    />
    <ListPreference android:key="abc"
        android:title="@string/abc"
        android:summary="@string/cde"
        android:persistent="true"/>

</PreferenceScreen>

И вы можете просто:

// the preference screen your item is in must be known
PreferenceScreen screen = (PreferenceScreen) findPreference("pref_key");

// the position of your item inside the preference screen above
int pos = findPreference("abc").getOrder();

// simulate a click / call it!!
screen.onItemClick( null, null, pos, 0 ); 

И появляется диалоговое окно!

Было бы неплохо получить PreferenceScreen a Preference (так что вам не нужно было знать, где находится ваш Preference), потому что перемещение предпочтения/изменение XML могло бы автоматически отключить автоматический диалог и не может быть замечено (если не проверено).

Для этого я написал функцию, которая будет выполнять поиск по всем настройкам и вернет PreferenceScreen ваше предпочтение, поэтому вам не нужно иметь ключ PreferenceScreen!

private PreferenceScreen findPreferenceScreenForPreference( String key, PreferenceScreen screen ) {
    if( screen == null ) {
        screen = getPreferenceScreen();
    }

    PreferenceScreen result = null;

    android.widget.Adapter ada = screen.getRootAdapter();
    for( int i = 0; i < ada.getCount(); i++ ) {
        String prefKey = ((Preference)ada.getItem(i)).getKey();
        if( prefKey != null && prefKey.equals( key ) ) {
            return screen;
        }
        if( ada.getItem(i).getClass().equals(android.preference.PreferenceScreen.class) ) {
            result = findPreferenceScreenForPreference( key, (PreferenceScreen) ada.getItem(i) );
            if( result != null ) {
                return result;
            }
        }
    }

    return null;
}

private void openPreference( String key ) {
    PreferenceScreen screen = findPreferenceScreenForPreference( key, null );
    if( screen != null ) {
        screen.onItemClick(null, null, findPreference(key).getOrder(), 0);
    }
}

// With this, you can call your `Preference` like this from code, you do
// not even have to give your PreferenceScreen a key!
openPreference( "abc" );

Ответ 3

 PreferenceScreen preferenceScreen  = (PreferenceScreen) findPreference("pref_key");
    final ListAdapter listAdapter = preferenceScreen.getRootAdapter();
         EditTextPreference editPreference = (EditTextPreference)   findPreference("set_password_preference");

    final int itemsCount = listAdapter.getCount();
    int itemNumber;
    for (itemNumber = 0; itemNumber < itemsCount; ++itemNumber) {
        if (listAdapter.getItem(itemNumber).equals(editPreference)) {
            preferenceScreen.onItemClick(null, null, itemNumber, 0);
            break;
        }
    }
     }
 }  

Ответ 4

Улучшение ответа deepak goel:

private void openPreference(String key) {
    PreferenceScreen preferenceScreen = getPreferenceScreen();
    final ListAdapter listAdapter = preferenceScreen.getRootAdapter();

    final int itemsCount = listAdapter.getCount();
    int itemNumber;
    for (itemNumber = 0; itemNumber < itemsCount; ++itemNumber) {
        if (listAdapter.getItem(itemNumber).equals(findPreference(key))) {
            preferenceScreen.onItemClick(null, null, itemNumber, 0);
            break;
        }
    }
}

Ответ 5

Если вы используете библиотеку поддержки, вы можете легко открыть диалог с PreferenceManager.showDialog(Предпочтение).

В вашем PreferenceFragmentCompat:

getPreferenceManager().showDialog(findPreference("pref_name"));

Обратите внимание, что в пакете предпочтений поддержки есть много проблем: нематериальный стиль и он сработает при повороте с открытым диалогом.

Ответ 6

wait, и вы можете сделать что-то вроде этого

Preference p=findPreference("settings_background_color");
p.setOnPreferenceClickListener(new OnPreferenceClickListener() {

    @Override
    public boolean onPreferenceClick(Preference preference) {

        int color=PreferenceManager.getDefaultSharedPreferences(ALifePatternsWallpaperSettings.this).getInt("settings_background_color", Color.BLACK);
        new ColorPickerDialog(ALifePatternsWallpaperSettings.this, ALifePatternsWallpaperSettings.this, "settings_background_color", color, Color.BLACK).show();
        return true;
    }
});

Ответ 7

Привет, друзья, попробуйте этот код в хорошем состоянии

getPreferenceManager().findPreference("YOUR PREF_KEY").setOnPreferenceClickListener(new OnPreferenceClickListener()
        {
            public boolean onPreferenceClick(Preference preference)
            {

                //your code here
                return true;
            }
        });