2011-10-21 13 views
16

Estoy desarrollando aplicaciones con minSdkVersion = "11", es decir, aplicaciones para tabletas y Android 4.0 y posteriores. He revisado internet sobre este tema, pero no he encontrado mucho.android: cómo establecer un diseño personalizado para PreferenceActivity en Android 3.0?

Para implementar el diseño personalizado para las versiones anteriores de Android SDK solo tenemos que crear el diseño (digamos preference.xml) con ListView y su id es igual a android.R.id.list y usar el método setContentView.

preference.xml:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" > 
    <ListView android:id="@android:id/list" 
       android:layout_width="fill_parent" 
       android:layout_height="fill_parent" /> 
</RelativeLayout> 

En Android 3.0 cosas han cambiado y las preferencias son implementadas con el uso de fragmentos. Así es como mi archivo preference_headers.xml parece:

<preference-headers 
     xmlns:android="http://schemas.android.com/apk/res/android"> 

    <header android:fragment="com.example.MyPreferenceActivity$GeneralSettingsFragment" 
      android:title="General" 
      android:summary="Common settings." /> 
    <header 
      android:title="Example.com" > 
     <intent android:action="android.intent.action.VIEW" 
       android:data="http://www.example.com" /> 
    </header> 

</preference-headers> 

MyPreferenceActivity.java:

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

     setContentView(R.layout.preference); 
     // Add a button to the header list. 
     if (hasHeaders()) { 
      Button button = new Button(this); 
      button.setText("Log out"); 
      setListFooter(button); 

     } 

    } 


    /** 
    * Populate the activity with the top-level headers. 
    */ 
    @Override 
    public void onBuildHeaders(List<Header> target) { 
     loadHeadersFromResource(R.xml.preference_headers, target); 
    } 

    public static class GeneralSettingsFragment extends PreferenceFragment { 
     @Override 
     public void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 

      // Load the preferences from an XML resource 
      addPreferencesFromResource(R.xml.fragmented_preferences); 

     } 
    } 
} 

Ahora si me quedo MyPreferenceActivity voy a ver este error en LogCat:

> java.lang.IllegalArgumentException: No view found for id 0x10202be for 
> fragment GeneralSettingsFragment{4077f8c0 #0 id=0x10202be} 
> E/AndroidRuntime(17103): at 
> android.app.FragmentManagerImpl.moveToState(FragmentManager.java:729) 
> E/AndroidRuntime(17103): at 
> android.app.FragmentManagerImpl.moveToState(FragmentManager.java:926) 
> E/AndroidRuntime(17103): at 
> android.app.FragmentManagerImpl.moveToState(FragmentManager.java:909) 
> E/AndroidRuntime(17103): at 
> android.app.FragmentManagerImpl.dispatchStart(FragmentManager.java:1584) 
> E/AndroidRuntime(17103): at 
> android.app.Activity.performStart(Activity.java:4377) 
> E/AndroidRuntime(17103): at 
> android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1724) 
> E/AndroidRuntime(17103): ... 11 more 

I saber qué causa este problema FragmentManager simplemente no puede encontrar una vista para insertar el fragmento GeneralSettingsFragment in. Pero no sé cómo resolverlo.

Por cierto, si me quedo la misma aplicación en Android 4.0, entonces se puede ver la primera preferencia de actividad con las cabeceras. Pero si hago clic en general, la aplicación se bloqueará y voy a recibir el error similar en LogCat:

java.lang.IllegalArgumentException: No view found for id 0x10202cd for fragment GeneralSettingsFragment{4134b4e0 #0 id=0x10202cd} 
E/AndroidRuntime(2170):  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:789) 
E/AndroidRuntime(2170):  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:998) 
E/AndroidRuntime(2170):  at android.app.BackStackRecord.run(BackStackRecord.java:622) 
E/AndroidRuntime(2170):  at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1330) 
E/AndroidRuntime(2170):  at android.app.Activity.performStart(Activity.java:4474) 
E/AndroidRuntime(2170):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1928) 
+0

¿Qué estás tratando de hacer? ¿Por qué necesitas un diseño personalizado? – alexanderblom

+0

Quiero tener un control más preciso sobre la Actividad de preferencia. Además, quiero que sea compatible con las versiones más recientes de Android SDK tanto como sea posible, es decir, necesito extender PreferenceActivity, pero no implementarlo yo mismo desde cero. – morphium

Respuesta

-1

que no es necesario setContenView. en este caso de ejemplo, la población de disposición se realiza a través de encabezados y fragmentos asociados, otras palabras automáticamente.

+0

Sé que no es necesario. Pero en este ejemplo agregué el botón al pie de página de la Lista. Ahora quiero personalizar la vista de manera más precisa. Tal vez agregando un logo en la parte superior de la actividad, etc. Es decir, lo necesito. Simplemente no entiendo, hay muchos ejemplos y tutoriales sobre la personalización de PreferenceActivity para aplicaciones anteriores a Android 3.0. ¿Es imposible hacer que funcione para API SDK mayor que 10? – morphium

2

i probado este código para mi aplicación

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> 
    <PreferenceCategory android:title="@string/PreferencesActivity.GeneralSettingsCategoryTitle"> 
     <Preference 
      android:title="yor title" 
      android:summary="your summary" 
      android:key="key to access preference" />  
     <Preference 
      android:title="@string/" 
      android:summary="@string/" 
      android:key="key2" /> 
     <PreferenceScreen 
      android:key="key3" 
      android:title="@string/" 
      android:summary="@string/"> 
      <CheckBoxPreference 
       android:title="@string/" 
       android:defaultValue="false" 
       android:summary="@string/" 
       android:key="key4" /> 
      <CheckBoxPreference 
       android:title="@string/" 
       android:defaultValue="true" 
       android:summary="@string/" 
       android:key="key5" /> 

      <ListPreference 
       android:title="@string/" 
       android:summary="@string/" 
       android:key="key6" 
       android:defaultValue="buttons" 
       android:entries="@array/" 
       android:entryValues="@array/" /> 
      .... 


       </prefefenceScreen> 
     </preferenceCategory> 
</preferenceScreen> 



enter code here 
5

que tenía el mismo problema que tú.

He intentado un montón de cosas, pero aquí es mi código completo:

https://github.com/iRail/BeTrains-for-Android/blob/master/src/tof/cv/mpp/MyPreferenceActivity.java

El truco es añadir el setContentView en la sección onBuildHeaders, pero no en el onCreate.

También hice algunas pruebas en el fragmento y no estar perfectamente seguro de por qué esto está funcionando, pero te prometo: Tengo un diseño personalizado en la sección de encabezado de la tableta!

https://github.com/iRail/BeTrains-for-Android/blob/master/src/tof/cv/mpp/view/StockPreferenceFragment.java

+5

Los enlaces están rotos – Dave

+0

el enlace está roto, pero pude encontrarlo: https://github.com/iRail/BeTrains-for-Android/blob/master/BeTrains/src/main/java/tof/cv/ mpp/MyPreferenceActivity.java – Glaucus

+0

Sin embargo, no vi una llamada a setContentView en onBuildHeaders. Entonces no estoy seguro de qué pensar. – Glaucus

Cuestiones relacionadas