为什么findPreference(key)返回null?

时间:2019-05-15 07:56:30

标签: java android

当我使用findPreference(key)获取首选项的特定部分并动态添加值时,我得到的是null。

我不知道我在做什么错。我尝试了其他使用findPreference()方法的方法。我浏览了有关Stackoverflow的教程和问答,但都没有成功。

这是我的SettingsActivity代码:

public class SettingsActivity extends AppCompatActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        FragmentManager fm = getSupportFragmentManager();
        SettingsFragment sf = new SettingsFragment();
        fm.beginTransaction()
                .replace(R.id.content, sf)
                .commit();

        setContentView(R.layout.activity_settings);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        sf.addCustomList("pref_key_calendar", new CharSequence[]{"One", "Two", "Three"}, new CharSequence[]{ "1", "2", "3" });
    }

    public static class SettingsFragment extends PreferenceFragmentCompat {

        @Override
        public void onCreatePreferences(Bundle savedInstanceState, String rootkey) {
            setPreferencesFromResource(R.xml.pref_settings, rootkey);
        }
        public void addCustomList(String key, CharSequence[] entries, CharSequence[] entryValues) {

            ListPreference customListPref = (ListPreference) findPreference(key);
            customListPref.setEntries(entries);
            customListPref.setEntryValues(entryValues);
        }
    }
}

这是带有参考的XML:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
    xmlns:android="http://schemas.android.com/apk/res/android">

        <PreferenceCategory
            android:title="Main"
            android:key="pref_key_settings_main">

            <ListPreference
                android:key="pref_key_calendar"
                android:title="@string/pref_key_calendar"
                android:summary="@string/pref_key_calendar_descr"
                />
            <SwitchPreference
                android:key="pref_key_review"
                android:title="@string/pref_key_review"
                android:summary="@string/pref_key_review_descr"
                />
            <Preference
                android:key="pref_key_review_time"
                android:title="@string/pref_key_review_time"
                android:summary="@string/pref_key_review_time_descr"
                />
            <ListPreference
                android:key="pref_key_read"
                android:title="@string/pref_key_read"
                android:summary="@string/pref_key_read_descr"
                android:defaultValue="2"
                android:entries="@array/pref_read_list_titles"
                android:entryValues="@array/pref_read_list_values"
                />
        </PreferenceCategory>
</PreferenceScreen>

我将不得不用安装的日历列表替换new CharSequence[]{"One", "Two", "Three"}-这就是为什么必须从SettingsActivity类调用sf.addCustomList的原因。

当我进入设置屏幕时,就会发生此错误(addCustomList()函数中setEntries()执行时的行号点):

FATAL EXCEPTION: main
Process: com.package1.novamowa, PID: 22093
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.package1.novamowa/com.silverdragon.kalafono.SettingsActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.preference.ListPreference.setEntries(java.lang.CharSequence[])' on a null object reference
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3194)
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3302)
                      at android.app.ActivityThread.-wrap12(Unknown Source:0)
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1891)
                      at android.os.Handler.dispatchMessage(Handler.java:108)
                      at android.os.Looper.loop(Looper.java:166)
                      at android.app.ActivityThread.main(ActivityThread.java:7425)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
                   Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.preference.ListPreference.setEntries(java.lang.CharSequence[])' on a null object reference
                      at com.silverdragon.kalafono.SettingsActivity$SettingsFragment.addCustomList(SettingsActivity.java:47)
                      at com.silverdragon.kalafono.SettingsActivity.onCreate(SettingsActivity.java:35)
                      at android.app.Activity.performCreate(Activity.java:7383)
                      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1218)
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3147)
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3302) 
                      at android.app.ActivityThread.-wrap12(Unknown Source:0) 
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1891) 
                      at android.os.Handler.dispatchMessage(Handler.java:108) 
                      at android.os.Looper.loop(Looper.java:166) 
                      at android.app.ActivityThread.main(ActivityThread.java:7425) 
                      at java.lang.reflect.Method.invoke(Native Method) 
                      at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921) 

我想知道-这个项目是从另一个项目复制而软件包名称已更改。它不应该影响findPreference()的执行,对吗? 请帮忙!

编辑:我已经解决了这个问题。

@SuppressLint("ValidFragment")
    public static class SettingsFragment extends PreferenceFragmentCompat {
        SettingsActivity invoker;

        @SuppressLint("ValidFragment")
        public SettingsFragment(SettingsActivity invoker) {
            super();
            this.invoker = invoker;
        }

        @Override
        public void onCreatePreferences(Bundle savedInstanceState, String rootkey) {
            setPreferencesFromResource(R.xml.pref_settings, rootkey);

            CalendarList cl = invoker.getListOfCalendars();
            String[] ids = cl.ids.toArray(new String[cl.ids.size()]);
            String[] names = cl.names.toArray(new String[cl.names.size()]);

            ListPreference customListPref = (ListPreference) findPreference("pref_key_calendar");
            customListPref.setEntries(names);
            customListPref.setEntryValues(ids);
        }
    }

使用invoker作为参数将构造函数添加到SettingsFragments允许我回调getListOfCalendars()函数,并使用结果将其添加到层次结构中的相应ListPreference点。

我不知道为什么IDE强迫我添加此@SuppressLint(“ ValidFragment”)批注,但是程序可以正常工作,所以我不在乎:)。

如果有人认为我的解决方案不正确,我将很高兴听到您的建议。

干杯!

0 个答案:

没有答案