2012-01-29 13 views
6

estoy tratando de añadir un support.v4.app.Fragment a un PreferenceActivity cabecera, así:Android: solución para support.v4.app.Fragment -> Fragment classcastexception?

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

Esto arroja una ClassCastException, presumiblemente debido a la PreferenceActivity está esperando una subclase de android.app.Fragment, en lugar de support.v4.app.Fragment.

Mi caso de uso es este:
Tengo un Fragmento no estándar que quiero usar como preferencia tanto en < 3.0 como en> 3.0 dispositivos. Para> = 3.0, necesito una subclase android.app.Fragment para que se pueda incrustar en el 'panel de detalles' de la actividad de preferencias en dispositivos tablet. Para < 3.0, necesito una subclase v4.support.app.Fragment para que pueda arrojar un ActivityFragment.

¿Existe alguna solución que me permita utilizar un Fragmento de compatibilidad en esta situación?

Respuesta

7

PreferenceFragment no está en el paquete de soporte de Android, y no puede usar una clase de fragmento de paquete de soporte de Android en un PreferenceActivity de esta manera. Por otra parte, sus encabezados no funcionarían en Android 2.x de todos modos, ya que el PreferenceActivity en Android 2.x no sabe acerca de los fragmentos.

En principio, puede bifurcar PreferenceActivity desde el código fuente para crear uno que sí utiliza la versión de soporte de Android Fragment.

O organice sus preferencias para usar fragmentos en Android 3.0+ y evitarlos en Android 2.x. Here is a sample project donde demuestro una manera de hacerlo.

+0

Lo siento, no creo que la solución de @CommonsWare sea perfecta. En realidad, necesitamos un PreferenceFragment compat. Debido a que PreferenceFragment se puede colocar en cualquier diseño de cualquier actividad, incluso la actividad se extiende desde ActionBarActivity. PreferenceActivity no se extiende desde ActionBarActivity, no tiene un diseño de ActionBar uniforme en todas las versiones de Android. – Lei

2

Como señala @CommonsWare, no es posible lo que quería sin volver a escribir PreferenceActivity, y eso parece una carga de trabajo.

La solución no tan elegante en la que me decidí fue crear dos PreferenceActivities (as shown here) y también crear dos subclases de Fragment, una para cada sabor de Fragment.

Así, PrefsActivityHC añade esta cabecera:

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

... mientras PrefsActivity añade esta preferencia:

<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> 

Para reducir al mínimo la cantidad de duplicación de código necesario para tener dos fragmentos casi idénticos, Creé una clase MyFragmentDelegate que admite métodos de fragmento comunes y una instancia de eso en MyFragment y MyFragmentHC. Las llamadas a los métodos en estos fragmentos se envían al delegado:

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) 
    } 
} 
Cuestiones relacionadas