Mantenga la barra de acciones visualizada al cambiar PreferenceScreen

Estoy intentando mostrar una barra de acción en mi pantalla de preferencias. Para ello, agregué el código siguiente en mi SettingActivity

public class PreferencesActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.preferences_activity); getFragmentManager().beginTransaction() .replace(R.id.container, new PreferencesFragment()).commit(); getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_HOME_AS_UP); getSupportActionBar().setDisplayHomeAsUpEnabled(true); } } 

Entonces el resto de mi código en PreferencesFragment. Esto funciona bien, pero tan pronto como pulse una preferencia de Preferencia, la barra de acciones se oculta. Si vuelvo a la pantalla principal de preferencias, puedo verla de nuevo. ¿Alguna idea de cómo mantener la barra de acciones desplegada (y actualizada con la etiqueta PreferenceScreen)?

Edit: Mirando el código de PreferenceScreen se parece a una pantalla completa El diálogo se abre cuando se hace clic en el PreferenceScreen. Debido a que mi preferencia tiene un título, el diálogo debe mostrar un título también … pero no

  // Set the title bar if title is available, else no title bar final CharSequence title = getTitle(); Dialog dialog = mDialog = new Dialog(context, context.getThemeResId()); if (TextUtils.isEmpty(title)) { dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE); } else { dialog.setTitle(title); } 

Finalmente me las arreglé para encontrar una manera de hacer esto. Es un poco feo, pero funciona.

Primero agrego una misma intención a todas las definiciones de PreferenceScreen en mi archivo preferences.xml (asegúrese de actualizar el valor del parámetro extra)

  <PreferenceScreen android:key="pref1" android:summary="Summary1" android:title="Title1" > <intent android:action="android.intent.action.VIEW" android:targetPackage="my.package" android:targetClass="my.package.activity.PreferencesActivity" > <extra android:name="page" android:value="pref1" /> </intent> ... </PreferenceScreen> 

BTW my.package.activity.PreferencesActivity es mi actividad de preferencia actual

Luego agrego un filtro de intenciones en el Manifiesto

  <activity android:name=".activity.PreferencesActivity" android:configChanges="keyboardHidden|orientation|screenSize" android:label="@string/settings" > <intent-filter android:label="Pref" > <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.PREFERENCE" /> </intent-filter> </activity> 

Añado un cierto código en el PreferenceActivity para manejar esto

  @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.preferences_activity); this.fragment = new PreferencesFragment(); this.fragment.setActivityIntent(getIntent()); getFragmentManager().beginTransaction() .replace(R.id.container, this.fragment).commit(); } 

Finalmente agrego el código siguiente en mi clase PreferencesFragment

  public void setActivityIntent(final Intent activityIntent) { if (activityIntent != null) { if (Intent.ACTION_VIEW.equals(activityIntent.getAction())) { if (intent.getExtras() != null) { final String page = intent.getExtras().getString("page"); if (!TextUtils.isEmpty(page)) { openPreferenceScreen(page); } } } } private void openPreferenceScreen(final String screenName) { final Preference pref = findPreference(screenName); if (pref instanceof PreferenceScreen) { final PreferenceScreen preferenceScreen = (PreferenceScreen) pref; ((PreferencesActivity) getActivity()).setTitle(preferenceScreen.getTitle()); setPreferenceScreen((PreferenceScreen) pref); } } 

Tenía el mismo problema. Nested PreferenceScreen s no tiene un ActionBar. Después de pasar por el código, parece ser causado por un conflicto entre AppCompatActivity y PreferenceScreen .

Por un lado, AppCompatActivity proporciona su propia barra de acción y, por lo tanto, requiere un tema descendente de Theme.AppCompat que especifica windowNoTitle = true alguna parte (no se pudo identificar exactamente dónde). Por otro lado – PreferenceScreen utiliza la plataforma Dialog con el tema de actividad (en lugar de sub-tema, por ejemplo, dialogTheme ). Podría ser un error.

Si no te importa Theme.AppCompat , Theme.AppCompat aquí una solución sencilla que funciona en la API 21+:

  • android.preference.PreferenceActivity como la clase base para su actividad
  • Crear un tema para esa actividad:

     <!-- This theme is used to show ActionBar on sub-PreferenceScreens --> <style name="PreferenceTheme" parent=""> <item name="android:windowActionBar">true</item> <item name="android:windowNoTitle">false</item> </style> 
  • Especifique android:theme="@style/PreferenceTheme" para esta actividad en el AndroidManifest.xml

Lo que obtendrás es más como un título de ventana estándar que un ActionBar completo. Todavía no he averiguado cómo agregar un botón de trabajo, etc.

Si desea seguir siendo compatible con AppCompatActivity y los temas relacionados, deberá solicitar FEATURE_NO_TITLE en la ventana de actividad. De lo contrario, terminará con dos barras de acción (la integrada en la parte superior y el soporte en la parte inferior) en la pantalla de PreferenceScreen nivel superior.

He hecho una aplicación que tiene una barra de acción en la actividad de preferencias. Parece que no puedo ver la clave para hacerlo, aunque sí recuerdo que me tomó algún tiempo clavarla bien.

Parece que nuestros códigos son bastante similares. Lo único que me llama la atención es esta importación: import android.support.v7.app.ActionBarActivity;

Déjeme saber si eso ayuda a cualquier

 public class SettingsActivity extends ActionBarActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getFragmentManager().beginTransaction().replace(android.R.id.content, new PrefsFragment() ).commit(); } // End of onCreate static public class PrefsFragment extends PreferenceFragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.preferences); // Load the preferences from an XML resource } } // end of PrefsFragment } 

Además: ¿tienes esto en tu styles.xml?

 <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> </style> 

Pero tan pronto como pulse una preferencia de Preferencia, la barra de acciones se oculta. Si vuelvo a la pantalla principal de preferencias, puedo verla de nuevo.

Supongo que está lanzando una nueva actividad cuando se hace clic en la preferencia

Tu fragmento Preferencia debería tener este aspecto

  public static class PreferencesFragment extends PreferenceFragment { public PlaceholderFragment() { } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.your_preferences); } } 

Luego muestre sus preferencias como se muestra a continuación

 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="fill_parent" android:layout_width="fill_parent" > <PreferenceCategory android:title="@string/pref_category_title"> <PreferenceScreen android:title="@string/title" android:summary="@string/summary"> <intent android:targetClass="com.your.package.Youractivity " android:targetPackage="com.your.package"/> </PreferenceScreen> <PreferenceScreen android:title="@string/another_title"> <intent android:targetClass="com.your.package.activity2" android:targetPackage="com.your.package.activity"/> </PreferenceScreen> </PreferenceCategory> 

Y, finalmente, lo principal Youractivity debe extenderse desde ActionBarActivity

  public class Youractivity extends ActionBarActivity { } 

El código anterior funciona para mí.

Como mencionaste en la pregunta, el Dialog pantalla completa podría ser un problema.

Intente cambiar el estilo de Dialog a:

 <style name="Theme.Holo.Dialog"> 

O al estilo que tiene estas propiedades:

 <item name="windowActionBar">true</item> <item name="windowNoTitle">false</item> 

Aquí puede leer cómo obtener referencia al Dialog .

Nota: Sólo para API> = 14

Fuente1 y Fuente2

PreferenciaActividad1.java

 public class PreferenceActivity1 extends android.preference.PreferenceActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.pref1); } @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); LinearLayout root = (LinearLayout)findViewById(android.R.id.list).getParent().getParent().getParent(); Toolbar bar = (Toolbar) LayoutInflater.from(this).inflate(R.layout.settings_toolbar, root, false); root.addView(bar, 0); // insert at top bar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } }); } } 

PreferenciaActividad2.java

 public class PreferenceActivity2 extends android.preference.PreferenceActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.pref2); } @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); LinearLayout root = (LinearLayout)findViewById(android.R.id.list).getParent().getParent().getParent(); Toolbar bar = (Toolbar) LayoutInflater.from(this).inflate(R.layout.settings_toolbar, root, false); root.addView(bar, 0); // insert at top bar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } }); } } 

Settings_toolbar.xml (diseño)

 <?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/toolbar" app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" android:layout_width="match_parent" android:layout_height="wrap_content" android:minHeight="?attr/actionBarSize" app:navigationContentDescription="@string/abc_action_bar_up_description" android:background="?attr/colorPrimary" app:navigationIcon="?attr/homeAsUpIndicator" app:title="@string/app_name" /> 

Pref1.xml (xml)

 <?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" android:theme="@android:style/Theme.Light" > <PreferenceCategory android:title="Main Preferences" > <CheckBoxPreference android:key="wifi enabled" android:title="WiFi" /> </PreferenceCategory> <PreferenceScreen android:key="key1" android:summary="" android:title="Wifi Settings" > <intent android:action="android.intent.action.VIEW" android:targetClass="com.example.PreferenceActivity2" android:targetPackage="com.example" /> </PreferenceScreen> </PreferenceScreen> 

Pref2.xml (xml)

 <?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" android:theme="@android:style/Theme.Light" > <PreferenceCategory android:title="Wifi Settings" > <CheckBoxPreference android:key="prefer wifi" android:title="Prefer WiFi" /> </PreferenceCategory> </PreferenceScreen> 

Manifiesto

 <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:name="com.example.PreferenceActivity1" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.example.PreferenceActivity2" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> </application> 

Resultado
Introduzca aquí la descripción de la imagen
Introduzca aquí la descripción de la imagen

Desde que Google tristemente no lo arregló hasta ahora, no es realmente una solución mucho más fácil:

  1. Establezca la clase SettingsActivity para que se extienda desde la "Actividad".

    public class SettingsActivity extends Activity { ...

  2. Cree un tema nuevo en la carpeta v21 / styles de SettingsActivty y establezca el padre en "Theme.Material. *"

    <style name="CustomThemeSettings" parent="android:Theme.Material"> <item name="android:colorPrimary">@color/...</item> <item name="android:colorPrimaryDark">@color/...</item> <item name="android:colorAccent">@color/...</item> </style>

  3. Establezca su nuevo tema en su archivo Manifest.xml:

    <activity android:name=".SettingsActivity" android:label="@string/title_activity_settingsactivity" android:theme="@style/CustomThemeSettings" > </activity>

  4. Simplemente funciona

  5. (Opcional) Si desea proporcionar soporte de diseño de material para dispositivos antiguos
    Puede poner SettingsActivity en una carpeta v21 + y crear otra SettingsActivity para dispositivos antiguos que tenga el AppCompat padre.

  • Android 5.0 - las casillas de verificación de las preferencias no son visibles
  • Inicio de Configuración Actividad de Preferencias XML funciona en 2.x pero no en 4.x
  • ¿Cómo manejar texto largo en las preferencias de Android?
  • Iniciar nueva actividad de PreferenceActivity
  • No se puede establecer la preferencia con PreferenceActivity
  • ActivityNotFoundException (YES, esta actividad se declara en AndroidManifest.xml)
  • NullPointerException en android.widget.ArrayAdapter.createViewFromResource
  • No puedo averiguar cómo usar un android PreferenciaActividad
  • Android: "BadTokenException: No se puede agregar ventana; Está funcionando su actividad? "Al mostrar el diálogo en PreferenciaActividad
  • Compatibilidad del edificio PreferenceFragment en Android
  • ¿PreferenceFragment con el fondo transparente?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.