See the new accepted answer for a much cleaner approach! This was working, but not really the clean way of doing it.
Damn it, it got me several hours, but it finally works.
The solution is the undocumented call public void onItemClick (...)
. It takes several arguments, and as pointed out by this question it can be used to simulate a click according to the index of the element you want to call.
My problem was the item I want to call is deeply nested in an XML-structure. But the solution is very easy: add a key
to the PreferenceScreen
the item you want to open is in:
<PreferenceScreen
android:key="pref_key"
....
/>
<ListPreference android:key="abc"
android:title="@string/abc"
android:summary="@string/cde"
android:persistent="true"/>
</PreferenceScreen>
And the you can just to the following:
// 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 );
And the Dialog pops up!
It would be nice to get the PreferenceScreen
a Preference
is in (so you would not have to know where your Preference
is in), because moving the preference/changing the XML could break the automatic dialog silently and might not get noticed (if not tested).
For this I wrote a function which will search through all preferences and return the PreferenceScreen
your preference is on, so you don't need to have your PreferenceScreen a key!
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" );
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…