如何在触发onPreferenceClick时动态填充ListPreference?

Abd*_*lah 30 android android-preferences

我有一个有偏好活动language作为ListPreference其显示可用的语言列表.我可以在调用onCreate时填充列表,但是当用户点击它时我想填写列表.

this is the java code :

public class SettingsActivity extends PreferenceActivity implements OnPreferenceClickListener {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        try {
            addPreferencesFromResource(R.xml.settings);
        } catch (Exception e) {

        }

    }

    @Override
    public boolean onPreferenceClick(Preference preference) {

        if((preference instanceof ListPreference) && (preference.getKey().equals("language"))){
            ListPreference lp = (ListPreference)preference;
            CharSequence[] entries = { "English", "French" };
            CharSequence[] entryValues = {"1" , "2"};
            lp.setEntries(entries);
            lp.setDefaultValue("1");
            lp.setEntryValues(entryValues);
            return true;
        }
        return false;

    }
}
Run Code Online (Sandbox Code Playgroud)

这是settings.xml(偏好):

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
  xmlns:android="http://schemas.android.com/apk/res/android">
    <PreferenceCategory android:title="General Settings">
        <CheckBoxPreference android:key="enabled"  android:title="Application Status" android:summary="Enable or disable the application" />
         <ListPreference 
         android:key="language" 
         android:title="Language"
         android:dialogTitle="Application language" 
         android:summary="Select the Application language"
         />
    </PreferenceCategory>
</PreferenceScreen>
Run Code Online (Sandbox Code Playgroud)

我搜索但没有找到结果!每次单击该列表时都会发生异常.

ccp*_*zza 51

您正在获取异常,因为您的ListPreference对象未初始化 - 您需要在XML中设置entriesentryValues属性,或者以编程方式执行onCreate().

如果您想要的是能够在初始化初始ListPreference对象之后动态更改列表中的项目,则需要将其OnPreferenceClickListener直接附加到ListPreference对象.使用您在XML中指定的密钥来获取首选项的句柄.

由于代码来填充entriesentryValues阵列将同时具有在将要运行onCreate()onPreferenceClick,是有意义的解压缩到一个单独的方法- setListPreferenceData()为了避免重复.

public class SettingsActivity extends PreferenceActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        try {
            addPreferencesFromResource(R.xml.settings);
        } catch (Exception e) {

        }

        final ListPreference listPreference = (ListPreference) findPreference("language");

        // THIS IS REQUIRED IF YOU DON'T HAVE 'entries' and 'entryValues' in your XML
        setListPreferenceData(listPreference);

        listPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() {
            @Override
            public boolean onPreferenceClick(Preference preference) {

                setListPreferenceData(listPreference);
                return false;
            }
        });
    }

    protected static void setListPreferenceData(ListPreference lp) {
            CharSequence[] entries = { "English", "French" };
            CharSequence[] entryValues = {"1" , "2"};
            lp.setEntries(entries);
            lp.setDefaultValue("1");
            lp.setEntryValues(entryValues);
    }
}
Run Code Online (Sandbox Code Playgroud)

以下是Google的DeskClock应用程序的另一个示例:

  • 这个答案有效,但是如果你让setListPreferenceData只运行onClick(而不是onCReate),它就会有点小问题.这是因为如果setListPreferenceData方法花费的时间超过一分之一,那么在设置数据之前会显示默认列表,并且用户被迫取消然后再次打开首选项.有没有办法更新setListPreferenceData完成后已经显示的listPreference? (3认同)
  • 如果你需要自定义行为,你最好的选择可能是扩展`ListPreference`或'Preference`.一个纯粹的"社交"解决方法是将默认列表项值设置为<loading ...> (3认同)

Cra*_*lWS 7

使用PreferenceFragment和JAVA设置密钥而不是PreferenceActivity和XML,如/sf/answers/968023871/所示,此答案基于:

如果您想要的是能够在初始化初始ListPreference对象之后动态更改列表中的项目,则需要将其OnPreferenceClickListener直接附加到ListPreference对象.使用您在JAVA源(as CUSTOM_LIST)中指定的密钥来获取首选项的句柄.

由于代码来填充entriesentryValues阵列则要既在运行onCreate()onPreferenceClick,是有意义的解压缩到一个单独的方法- setListPreferenceData()为了避免重复.

/**
 * This fragment shows data and sync preferences only. It is used when the
 * activity is showing a two-pane settings UI.
 */
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public static class myCustomPreferenceFragment extends PreferenceFragment {

    final private String CUSTOM_LIST= "custom_list";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.pref_custom_frag);

        PreferenceCategory targetCategory = (PreferenceCategory) findPreference("CUSTOM_FRAG");

        final ListPreference lp = setListPreferenceData((ListPreference) findPreference(CUSTOM_LIST), getActivity());

        lp.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
            @Override
            public boolean onPreferenceClick(Preference preference) {

                setListPreferenceData(lp, getActivity());
                return false;
            }
        });
        setHasOptionsMenu(true);
        targetCategory.addPreference(lp);

        bindPreferenceSummaryToValue(targetCategory);
        bindPreferenceSummaryToValue(lp);
    }

    protected ListPreference setListPreferenceData(ListPreference lp, Activity mActivity) {
        CharSequence[] entries = { "One", "Two", "Three" };
        CharSequence[] entryValues = { "1", "2", "3" };
        if(lp == null)
            lp = new ListPreference(mActivity);
        lp.setEntries(entries);
        lp.setDefaultValue("1");
        lp.setEntryValues(entryValues);
        lp.setTitle("Number Of blahs");
        lp.setSummary(lp.getEntry());
        lp.setDialogTitle("Number of Blah objects");
        lp.setKey(CUSTOM_LIST);
        return lp;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == android.R.id.home) {
            startActivity(new Intent(getActivity(), SettingsActivity.class));
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}
Run Code Online (Sandbox Code Playgroud)

XML布局:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <PreferenceCategory
        android:key="CUSTOM_FRAG"
        android:title="Some Options">

    </PreferenceCategory>
</PreferenceScreen>
Run Code Online (Sandbox Code Playgroud)