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 enAndroidManifest.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:
Establezca su clase de Configuración de Actividad para extender desde solo "Actividad".
public class SettingsActivity extends Activity { ...
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>
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 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