2012-01-29 19 views
6

我想添加一個support.v4.app.FragmentPreferenceActivity頭,像這樣:Android:解決方法support.v4.app.Fragment - >片段classcastexception?

<header 
    android:fragment="com.example.SupportFragmentSubClass" 
    android:title="Selecting this should show the accompanying fragment" > 
</header> 

這將引發一個ClassCastException,大概是因爲PreferenceActivity期待一個子類的android.app.Fragment,而不是support.v4.app.Fragment

我的用例是這樣的:
我有非標準的片段,我想用作偏好在< 3.0和> 3.0設備上。對於> = 3.0,我需要一個android.app.Fragment子類,以便它可以嵌入到平板設備上的首選項活動的「詳細信息窗格」中。對於< 3.0,我需要一個v4.support.app.Fragment子類,所以我可以在其中輸入ActivityFragment

有沒有一種解決方法可以讓我在這種情況下使用兼容性片段?

回答

7

PreferenceFragment不在Android支持包中,您不能使用這種方式在PreferenceActivity中使用Android支持包片段類。此外,無論如何,你的頭文件無法在Android 2.x上運行,因爲Android 2.x中的PreferenceActivity不知道片段。

原則上,您可以從源代碼中分離出PreferenceActivity,以創建一個使用Android支持版本Fragment的版本。

或者,將您的偏好設置爲在Android 3.0+上使用片段,並在Android 2.x上避免使用這些片段。 Here is a sample project我在那裏演示了一種方法來做到這一點。

+0

對不起,我不認爲@CommonsWare的解決方案是完美的。其實,我們需要一個PreferenceFragment compat。由於PreferenceFragment可以放置在任何活動的任何佈局中,即使該活動從ActionBarActivity擴展而來。 PreferenceActivity不從ActionBarActivity擴展,它在所有Android版本中沒有一致的ActionBar佈局。 – Lei 2013-08-20 10:03:28

2

正如@CommonsWare所指出的那樣,在不重寫PreferenceActivity的情況下,我想要的東西是不可能的,而且看起來像是一項工作。

我決定的不那麼優雅的解決方案是創建兩個PreferenceActivities(as shown here)並創建兩個片段子類,每個片段都有一個子類。

所以,PrefsActivityHC添加此標頭:

<header 
    <!-- An android.app.Fragment subclass --> 
    android:fragment="com.example.project.MyFragmentHC" 
</header> 

...而PrefsActivity添加此偏好:

<Preference> 
    <intent 
     <!-- A v4.support.app.Fragment subclass, wrapped in an ActivityFragment --> 
     android:targetClass="com.example.project.MyFragmentActivity" 
     android:targetPackage="com.example.project" > 
    </intent> 
</Preference> 

爲了最小化代碼重複的具有兩個幾乎相同的片段所需的量,我創建了一個支持通用片段方法的類MyFragmentDelegate,並在MyFragmentMyFragmentHC中保存了該類的一個實例。呼叫這些片段中的方法,然後只是轉發給代表:

class MyFragment { 

    MyFragmentDelegate mDelegate; 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     return mDelegate.onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
    } 
} 

class MyFragmentHC { 

    MyFragmentDelegate mDelegate; 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     return mDelegate.onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
    } 
} 
相關問題