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)?
- Usar getSupportFragmentManager () Dentro de PreferenceActivity
- ¿Cómo puedo seleccionar el encabezado predeterminado en mi PreferenceActivity en tabletas?
- Configuración de valores predeterminados de varias instancias / archivos de SharedPreferences
- ¿Cómo establecer el valor RingtonePreference del código?
- ActionBar en PreferenceFragment no volver a calcular la altura y el tamaño de fuente
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); }
- Omita los encabezados en PreferenciaActividad cuando sólo hay un encabezado
- ¿Es posible combinar un EditTextPreference con un CheckBoxPreference?
- ¿Cómo agregar un "oyente de clic largo" a una preferencia?
- Respondiendo a las actualizaciones de preferencias en Android
- Cómo cargar la misma preferencia de pantalla en el detalle PreferenceFragment
- Android PreferencesActivity para crear una preferencia MODE_WORLD_WRITEABLE entre aplicaciones
- Compatibilidad para SwitchPreference (pre ICS)?
- Cambiar dinámicamente el recurso widgetlayout de la preferencia de Android
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 elAndroidManifest.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
Desde que Google tristemente no lo arregló hasta ahora, no es realmente una solución mucho más fácil:
-
Establezca la clase SettingsActivity para que se extienda desde la "Actividad".
public class SettingsActivity extends Activity { ...
-
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>
-
Establezca su nuevo tema en su archivo Manifest.xml:
<activity android:name=".SettingsActivity" android:label="@string/title_activity_settingsactivity" android:theme="@style/CustomThemeSettings" > </activity>
-
Simplemente funciona
-
(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.
- ¿Cómo incluir un .so lib en el proyecto Intellij IDEA for Android?
- Android Honeycomb: NetworkOnMainThreadException incluso cuando se utiliza AsyncTask y no modo estricto?