我有一个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 (也适合我)。
看起来似乎没有可能从代码中做到这一点。
答案 0 :(得分:37)
查看新接受的答案以获得更清洁的方法!这是有效的,但并不是真正干净的方式。
解决方案是未记录的电话public void onItemClick (...)
。它需要几个参数,正如this question所指出的,它可以用来根据你想要调用的元素的索引来模拟一次点击。
我的问题是我要调用的项目是否嵌套在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
成为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" );
答案 1 :(得分:21)
您可以使用扩展的ListPreference来创建对话框,然后包含您自己的公共方法,该方法调用ListPreference的受保护的showDialog方法。类似的东西:
public void show()
{
showDialog(null);
}
通过这种方式,当有多个人在评论中指出你的答案时,你不会遇到getOrder()无法正常工作的问题。
这可以使用任何具有受保护的showDialog方法的首选项类型来完成。
答案 2 :(得分:8)
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;
}
}
}
}
答案 3 :(得分:4)
如果您使用支持库,则可以使用PreferenceManager.showDialog(Preference)轻松打开对话框。
在PreferenceFragmentCompat中:
getPreferenceManager().showDialog(findPreference("pref_name"));
请注意,支持首选项包有许多问题: non-material styling和 it crashes when rotated with an open dialog
答案 4 :(得分:3)
改善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 :(得分:0)
如果您使用的是AndroidX首选项库,则非常简单。
public class CustomPreferenceFragment extends PreferenceFragmentCompat {
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.your_preference);
DialogPreference dialogPreference = (DialogPreference) findPreference("your_preference_key");
onDisplayPreferenceDialog(dialogPreference);
}
}
答案 6 :(得分:-1)
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 :(得分:-1)
嗨朋友们可以试试这段代码
getPreferenceManager().findPreference("YOUR PREF_KEY").setOnPreferenceClickListener(new OnPreferenceClickListener()
{
public boolean onPreferenceClick(Preference preference)
{
//your code here
return true;
}
});