3

我正在關注this tutorial。因爲PreferenceActivity用於創建設置。不過有人提到我可以使用Fragments,所以我繼續使用PreferenceFrament進行正常的活動。但是,當我跑的應用程序,它應聲給予以下日誌 -PreferenceFragment中的RunTimeException

07-25 10:41:02.048 7515-7515/com.example.sunshine E/AndroidRuntime﹕ FATAL EXCEPTION: main 
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.sunshine/com.example.sunshine.SettingsActivity}: java.lang.RuntimeException: Content has view with id attribute 'android.R.id.list' that is not a ListView class 
      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2063) 
      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2088) 
      at android.app.ActivityThread.access$600(ActivityThread.java:134) 
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1199) 
      at android.os.Handler.dispatchMessage(Handler.java:99) 
      at android.os.Looper.loop(Looper.java:137) 
      at android.app.ActivityThread.main(ActivityThread.java:4744) 
      at java.lang.reflect.Method.invokeNative(Native Method) 
      at java.lang.reflect.Method.invoke(Method.java:511) 
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
      at dalvik.system.NativeStart.main(Native Method) 
    Caused by: java.lang.RuntimeException: Content has view with id attribute 'android.R.id.list' that is not a ListView class 
      at android.preference.PreferenceFragment.ensureList(PreferenceFragment.java:350) 
      at android.preference.PreferenceFragment.getListView(PreferenceFragment.java:336) 
      at android.preference.PreferenceFragment.bindPreferences(PreferenceFragment.java:330) 
      at android.preference.PreferenceFragment.onActivityCreated(PreferenceFragment.java:171) 
      at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:852) 
      at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1039) 
      at android.app.BackStackRecord.run(BackStackRecord.java:635) 
      at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1411) 
      at android.app.Activity.performStart(Activity.java:5017) 
      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2036) 
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2088) 
            at android.app.ActivityThread.access$600(ActivityThread.java:134) 
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1199) 
            at android.os.Handler.dispatchMessage(Handler.java:99) 
            at android.os.Looper.loop(Looper.java:137) 
            at android.app.ActivityThread.main(ActivityThread.java:4744) 
            at java.lang.reflect.Method.invokeNative(Native Method) 
            at java.lang.reflect.Method.invoke(Method.java:511) 
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
            at dalvik.system.NativeStart.main(Native Method) 

當我搜索了SO,我才知道飛機墜毀在一定程度上關係到ListFragment。但我確定我沒有在我的應用程序中使用它。 PreferenceFragment可能會調用它。我無法在這裏查明問題。你能幫我解決嗎?

下面是我使用的偏好XML -

<?xml version="1.0" encoding="utf-8"?> 

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    > 
    <EditTextPreference 
     android:title="@string/pref_location_label" 
     android:key="@string/pref_location_key" 
     android:defaultValue="@string/pref_location_default" 
     android:inputType="text" 
     android:singleLine="true" 
     /> 
</PreferenceScreen> 

而這裏的SettingsActivity,與片段一起 -

public class SettingsActivity extends Activity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_settings); 
     if (savedInstanceState == null) { 
      getFragmentManager().beginTransaction() 
        .add(R.id.container, new SettingsFragment()) 
        .commit(); 
     } 
    } 

    public static class SettingsFragment extends PreferenceFragment implements Preference.OnPreferenceChangeListener { 

     public SettingsFragment() { 
     } 

     @Override 
     public void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      // Add 'general' preferences, defined in the XML file 
      addPreferencesFromResource(R.xml.pref_general); 

      // For all preferences, attach an OnPreferenceChangeListener so the UI summary can be 
      // updated when the preference changes. 
      bindPreferenceSummaryToValue(findPreference(getString(R.string.pref_location_key))); 
     } 

     @Override 
     public View onCreateView(LayoutInflater inflater, ViewGroup container, 
       Bundle savedInstanceState) { 
      View rootView = inflater.inflate(R.layout.fragment_settings, container, false); 
      return rootView; 
     } 

     /** 
     * Attaches a listener so the summary is always updated with the preference value. 
     * Also fires the listener once, to initialize the summary (so it shows up before the value 
     * is changed.) 
     */ 
     private void bindPreferenceSummaryToValue(Preference preference) { 
      // Set the listener to watch for value changes. 
      preference.setOnPreferenceChangeListener(this); 

      // Trigger the listener immediately with the preference's 
      // current value. 
      onPreferenceChange(preference, 
        PreferenceManager 
          .getDefaultSharedPreferences(preference.getContext()) 
          .getString(preference.getKey(), "")); 
     } 

     @Override 
     public boolean onPreferenceChange(Preference preference, Object value) { 
      String stringValue = value.toString(); 

      if (preference instanceof ListPreference) { 
       // For list preferences, look up the correct display value in 
       // the preference's 'entries' list (since they have separate labels/values). 
       ListPreference listPreference = (ListPreference) preference; 
       int prefIndex = listPreference.findIndexOfValue(stringValue); 
       if (prefIndex >= 0) { 
        preference.setSummary(listPreference.getEntries()[prefIndex]); 
       } 
      } else { 
       // For other preferences, set the summary to the value's simple string representation. 
       preference.setSummary(stringValue); 
      } 
      return true; 
     } 
    } 
} 

還有什麼我需要改變,使其成爲碎片的工作,而不是活動?

回答

3

終於找到了。我只需要在我的片段的xml中添加一個帶有android:id="@id/android:list"屬性的ListView。雖然我不知道爲什麼我需要它,但只是通過反覆試驗才發現它。

+3

添加naveen ravindran發表的評論作爲答覆。 「如果有人想知道爲什麼要添加WORKS,那是因爲在(源代碼)首選項片段 - > bindpreferences()中,它實際上試圖在當前視圖中查找列表視圖(使用android.r.id.list)如果生成的視圖不是列表視圖,則會拋出上述異常。此列表對於顯示首選項是強制性的。「 (是的,我可以證實這也適用於我)。 – Robbie

+0

^這終於爲我修好了。 – Ken

1

看來,你的問題是在你的activity_settings.xml,因爲它說你是(據說),創建具有以下ID的觀點:android.R.id.list,這是不是一個ListView檢查activity_settings.xml,你可能會發現problema,否則交你的XML,看看是否有什麼問題。

+0

謝謝!雖然我已經解決了,但你的答案與我發現的很接近。 – noob

+0

很高興幫助:)! – zozelfelfo

2

一些更多的信息,除了由noob解決方案。如果有人想知道爲什麼要添加WORKS,那是因爲在(源代碼)偏好片段 - > bindpreferences()中,它實際上試圖在當前視圖中查找一個列表視圖(使用android.r.id.list)和如果結果視圖不是列表視圖,則會引發上述異常。該列表對於顯示首選項是強制性的。

+0

感謝您的解釋! – noob