Как открыть или имитировать щелчок на андроиде Предпочтение, созданное с помощью 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 (для меня тоже).
Похоже, что нет никакой возможности сделать это из кода.
Ответы
Ответ 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;
}
});