studio programacion para móviles libro edición desarrollo desarrollar curso aprende aplicaciones android android-actionbar preferenceactivity preferencefragment

para - manual de programacion android pdf



Mantenga la barra de acciones visualizada al cambiar PreferenceScreen (7)

He creado una aplicación que tiene una barra de acciones en la actividad de preferencias. Parece que no veo la clave para hacerlo, aunque recuerdo que me tomó un tiempo arreglarlo.

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

Avísame si eso ayuda

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: ¿tiene esto en su styles.xml?

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

Estoy tratando de mostrar una barra de acciones en mi pantalla de preferencias. Para hacerlo, agregué el siguiente código en 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); } }

luego el resto de mi código en PreferencesFragment. Esto funciona bien, pero tan pronto como presiono una preferencia de PreferenceScreen, la barra de acciones está oculta. Si vuelvo a la pantalla principal de preferencias, puedo volver a verla. ¿Alguna idea de cómo mantener la barra de acciones visualizada (y actualizada con la etiqueta PreferenceScreen)?

Editar: Al mirar el código PreferenceScreen, se ve como una pantalla completa. El cuadro de diálogo se abre cuando se hace clic en PreferenceScreen. Como mi preferencia tiene un título, el cuadro de diálogo también debe mostrar un título ... 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); }


pero tan pronto como presiono una preferencia de PreferenceScreen, la barra de acciones está oculta. Si vuelvo a la pantalla principal de preferencias, puedo volver a verla.

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

Su fragmento de Preferencia debería verse así

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

Luego muestra tus_preferencias como abajo

<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 de Youractivity debería extenderse desde ActionBarActivity

public class Youractivity extends ActionBarActivity { }

El código anterior funciona para mí.


Finalmente logré encontrar una manera de hacer esto. Es algo feo pero funciona.

Primero agrego el mismo Intento a cada definición 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 Preferencial actual

Luego agrego un filtro de intención 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>

Agregué un código en 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 siguiente código 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. Las PreferenceScreen pantalla anidadas no tienen una barra de acciones. Después de recorrer el código, parece ser causado por un conflicto entre AppCompatActivity y PreferenceScreen .

Por un lado, AppCompatActivity proporciona su propia barra de acciones y, por lo tanto, requiere un tema que desciende de Theme.AppCompat que especifica windowNoTitle = true algún lugar (no se pudo determinar exactamente dónde). Por otro lado, PreferenceScreen usa la plataforma Dialog con el tema de actividad (en lugar de un subtema, por ejemplo, dialogTheme ). Podría ser un error.

Si no te importa Theme.AppCompat , aquí hay una solución simple que funciona con API 21+:

  • usa android.preference.PreferenceActivity como la clase base para tu actividad
  • crea 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 AndroidManifest.xml

Lo que obtendrá es más como un título de ventana estándar que una barra de acción completa. Todavía no he descubierto cómo agregar un botón de retroceso 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ás con dos barras de acción (la integrada en la parte superior y la que está en la parte inferior) en la PreferenceScreen nivel superior.


Como Google lamentablemente no lo solucionó hasta ahora, en realidad hay una solución mucho más fácil:

  1. Establezca su clase de Configuración de Actividad para extender desde solo "Actividad".

    public class SettingsActivity extends Activity { ...

  2. Cree un nuevo tema en su carpeta v21 / styles para su SettingsActivty y establezca el elemento principal 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 materiales para dispositivos anteriores
    puede poner la actividad de configuración en una carpeta v21 + y crear otra configuración de actividad para dispositivos más antiguos que tiene el AppCompat principal.


Como mencionó en la pregunta, el cuadro de Dialog pantalla completa podría ser un problema.

Intenta 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 hacer referencia al Dialog .


Nota: solo para API> = 14

Fuente1 y Fuente2

PreferenceActivity1.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(); } }); } }

PreferenceActivity2.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 (layout)

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