Après la mise à niveau vers la bibliothèque de support v21, mon ActionBar dans mon PreferenceActivity
est parti.
Ai-je manqué certains attributs de mon thème pour le réactiver? J'ai eu des problèmes similaires avec une ActionBar noire .
J'ai également essayé de l'ajouter un peu hackish en ajoutant un Toolbar
à la disposition racine, mais cela n'a pas fonctionné comme prévu.
Réponses:
Veuillez trouver le dépôt GitHub: ici
Très similaire à votre propre code mais ajouté xml pour permettre le titre défini:
Continuer à utiliser
PreferenceActivity
:settings_toolbar.xml :
<?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/action_settings" />
SettingsActivity.java :
public class SettingsActivity extends PreferenceActivity { @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(); } }); } }
Result :
MISE À JOUR (compatibilité pain d'épice):
Comme indiqué ici , Gingerbread Devices renvoie NullPointerException sur cette ligne:
LinearLayout root = (LinearLayout)findViewById(android.R.id.list).getParent().getParent().getParent();
RÉPARER:
SettingsActivity.java :
public class SettingsActivity extends PreferenceActivity { @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); Toolbar bar; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { LinearLayout root = (LinearLayout) findViewById(android.R.id.list).getParent().getParent().getParent(); bar = (Toolbar) LayoutInflater.from(this).inflate(R.layout.settings_toolbar, root, false); root.addView(bar, 0); // insert at top } else { ViewGroup root = (ViewGroup) findViewById(android.R.id.content); ListView content = (ListView) root.getChildAt(0); root.removeAllViews(); bar = (Toolbar) LayoutInflater.from(this).inflate(R.layout.settings_toolbar, root, false); int height; TypedValue tv = new TypedValue(); if (getTheme().resolveAttribute(R.attr.actionBarSize, tv, true)) { height = TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics()); }else{ height = bar.getHeight(); } content.setPadding(0, height, 0, 0); root.addView(content); root.addView(bar); } bar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } }); } }
Tout problème avec ce qui précède, faites le moi savoir!
MISE À JOUR 2: CONTOURNEMENT DE TEINTE
Comme indiqué dans de nombreuses notes de développement,
PreferenceActivity
ne prend pas en charge la teinte des éléments, mais en utilisant quelques classes internes, vous POUVEZ y parvenir. C'est jusqu'à ce que ces classes soient supprimées. (Fonctionne avec le support appCompat-v7 v21.0.3).Ajoutez les importations suivantes:
import android.support.v7.internal.widget.TintCheckBox; import android.support.v7.internal.widget.TintCheckedTextView; import android.support.v7.internal.widget.TintEditText; import android.support.v7.internal.widget.TintRadioButton; import android.support.v7.internal.widget.TintSpinner;
Remplacez ensuite la
onCreateView
méthode:@Override public View onCreateView(String name, Context context, AttributeSet attrs) { // Allow super to try and create a view first final View result = super.onCreateView(name, context, attrs); if (result != null) { return result; } if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { // If we're running pre-L, we need to 'inject' our tint aware Views in place of the // standard framework versions switch (name) { case "EditText": return new TintEditText(this, attrs); case "Spinner": return new TintSpinner(this, attrs); case "CheckBox": return new TintCheckBox(this, attrs); case "RadioButton": return new TintRadioButton(this, attrs); case "CheckedTextView": return new TintCheckedTextView(this, attrs); } } return null; }
Result:
AppCompat 22.1
AppCompat 22.1 a introduit de nouveaux éléments teintés, ce qui signifie qu'il n'est plus nécessaire d'utiliser les classes internes pour obtenir le même effet que la dernière mise à jour. Au lieu de cela, suivez ceci (toujours prioritaire
onCreateView
):@Override public View onCreateView(String name, Context context, AttributeSet attrs) { // Allow super to try and create a view first final View result = super.onCreateView(name, context, attrs); if (result != null) { return result; } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { // If we're running pre-L, we need to 'inject' our tint aware Views in place of the // standard framework versions switch (name) { case "EditText": return new AppCompatEditText(this, attrs); case "Spinner": return new AppCompatSpinner(this, attrs); case "CheckBox": return new AppCompatCheckBox(this, attrs); case "RadioButton": return new AppCompatRadioButton(this, attrs); case "CheckedTextView": return new AppCompatCheckedTextView(this, attrs); } } return null; }
ÉCRANS DE PRÉFÉRENCE EMBARQUÉS
Beaucoup de gens rencontrent des problèmes pour inclure la barre d'outils dans les
<PreferenceScreen />
s imbriqués , cependant, j'ai trouvé une solution !! - Après de nombreux essais et erreurs!Ajoutez ce qui suit à votre
SettingsActivity
:@SuppressWarnings("deprecation") @Override public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { super.onPreferenceTreeClick(preferenceScreen, preference); // If the user has clicked on a preference screen, set up the screen if (preference instanceof PreferenceScreen) { setUpNestedScreen((PreferenceScreen) preference); } return false; } public void setUpNestedScreen(PreferenceScreen preferenceScreen) { final Dialog dialog = preferenceScreen.getDialog(); Toolbar bar; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { LinearLayout root = (LinearLayout) dialog.findViewById(android.R.id.list).getParent(); bar = (Toolbar) LayoutInflater.from(this).inflate(R.layout.settings_toolbar, root, false); root.addView(bar, 0); // insert at top } else { ViewGroup root = (ViewGroup) dialog.findViewById(android.R.id.content); ListView content = (ListView) root.getChildAt(0); root.removeAllViews(); bar = (Toolbar) LayoutInflater.from(this).inflate(R.layout.settings_toolbar, root, false); int height; TypedValue tv = new TypedValue(); if (getTheme().resolveAttribute(R.attr.actionBarSize, tv, true)) { height = TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics()); }else{ height = bar.getHeight(); } content.setPadding(0, height, 0, 0); root.addView(content); root.addView(bar); } bar.setTitle(preferenceScreen.getTitle()); bar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { dialog.dismiss(); } }); }
La raison pour laquelle cela
PreferenceScreen
est si pénible est parce qu'ils sont basés sur une boîte de dialogue enveloppante, nous devons donc capturer la disposition de la boîte de dialogue pour y ajouter la barre d'outils.Ombre de la barre d'outils
De par sa conception, l'importation de
Toolbar
ne permet pas d'élévation et d'ombrage dans les appareils antérieurs à la v21, donc si vous souhaitez avoir une élévation sur votre,Toolbar
vous devez l'envelopper dans unAppBarLayout
:`settings_toolbar.xml:
<android.support.design.widget.AppBarLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <android.support.v7.widget.Toolbar .../> </android.support.design.widget.AppBarLayout>
Sans oublier d'ajouter l'ajout de la bibliothèque Design Support en tant que dépendance dans le
build.gradle
fichier:compile 'com.android.support:support-v4:22.2.0' compile 'com.android.support:appcompat-v7:22.2.0' compile 'com.android.support:design:22.2.0'
Android 6.0
J'ai étudié le problème de chevauchement signalé et je ne peux pas reproduire le problème.
Le code complet utilisé comme ci-dessus produit les éléments suivants:
S'il me manque quelque chose, veuillez me le faire savoir via ce dépôt et j'enquêterai .
la source
android:theme
solution de contournement corrige uniquement la couleur du texte noir dans la barre d'outils pour Android 5.0+. Il apparaît comme quelque chose de changé avec la nouvelle bibliothèque de support (j'utilise 22.2.0).Utilisez AppCompatActivity & PreferenceFragment pour résoudre le problème:
AppCompatActivity:
public class SettingsActivity extends AppCompatActivity { @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); getFragmentManager().beginTransaction().replace(android.R.id.content, new SettingsFragment()).commit(); }}
PréférenceFragment:
public class SettingsFragment extends PreferenceFragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.settings_preferences); }}
la source
J'ai fini par ajouter moi-même la barre d'outils avec ce code simple:
// get the root container of the preferences list LinearLayout root = (LinearLayout)findViewById(android.R.id.list).getParent().getParent().getParent(); Toolbar bar = (Toolbar)LayoutInflater.from(this).inflate(R.layout.preferences_toolbar, root, false); root.addView(bar, 0); // insert at top bar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } });
Voici ma preferences_toolbar.xml:
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_height="wrap_content" android:layout_width="match_parent" android:minHeight="?attr/actionBarSize" app:navigationContentDescription="@string/abc_action_bar_up_description" android:background="?attr/colorPrimary" app:navigationIcon="?attr/homeAsUpIndicator" app:theme="@style/Theme.Toolbar" />
la source
Une meilleure solution que de "lancer votre propre" barre d'action consiste à utiliser la classe AppCompatDelegate , qui vous permet d' ajouter une barre d'action réelle et factuelle à partir de la bibliothèque de support. Voici un exemple de code pour l'utiliser, tiré de la réponse de Ľubomír Kučera à cette question .
... import android.support.v7.app.ActionBar; import android.support.v7.app.AppCompatDelegate; import android.support.v7.widget.Toolbar; ... public class SettingsActivity extends PreferenceActivity { private AppCompatDelegate mDelegate; @Override protected void onCreate(Bundle savedInstanceState) { getDelegate().installViewFactory(); getDelegate().onCreate(savedInstanceState); super.onCreate(savedInstanceState); } @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); getDelegate().onPostCreate(savedInstanceState); } public ActionBar getSupportActionBar() { return getDelegate().getSupportActionBar(); } public void setSupportActionBar(@Nullable Toolbar toolbar) { getDelegate().setSupportActionBar(toolbar); } @Override public MenuInflater getMenuInflater() { return getDelegate().getMenuInflater(); } @Override public void setContentView(@LayoutRes int layoutResID) { getDelegate().setContentView(layoutResID); } @Override public void setContentView(View view) { getDelegate().setContentView(view); } @Override public void setContentView(View view, ViewGroup.LayoutParams params) { getDelegate().setContentView(view, params); } @Override public void addContentView(View view, ViewGroup.LayoutParams params) { getDelegate().addContentView(view, params); } @Override protected void onPostResume() { super.onPostResume(); getDelegate().onPostResume(); } @Override protected void onTitleChanged(CharSequence title, int color) { super.onTitleChanged(title, color); getDelegate().setTitle(title); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); getDelegate().onConfigurationChanged(newConfig); } @Override protected void onStop() { super.onStop(); getDelegate().onStop(); } @Override protected void onDestroy() { super.onDestroy(); getDelegate().onDestroy(); } public void invalidateOptionsMenu() { getDelegate().invalidateOptionsMenu(); } private AppCompatDelegate getDelegate() { if (mDelegate == null) { mDelegate = AppCompatDelegate.create(this, null); } return mDelegate; } }
la source
Salut je ne suis pas si vous avez toujours ce problème. Mais je pense que je publierai ce que j'ai fait pour résoudre ce problème et j'espère que cela aidera quelqu'un.
1) Tout d'abord, vous avez peut-être remarqué que PreferenceActivity étend ListActivity qui à son tour s'étend de Activity.
Selon les commentaires sur le blog des développeurs ( http://android-developers.blogspot.com/2014/10/appcompat-v21-material-design-for-pre.html ), pour utiliser v21 toutes vos activités doivent hériter d'ActionBarActivity . Il y a donc votre problème.
2) Les étapes que j'ai utilisées pour résoudre sont:
a) Make sure that you set the Theme of your PreferenceActivity to inherits one ot the Theme.AppCompat Themes. b) Make your class PreferenceActivity extends ActionBarActivity. c) Use the PreferenceFragment as your container for all your preferences.
Cela devrait le résoudre.
À votre santé!
la source
J'ai fait quelque chose de similaire à la question acceptée, mais j'utilise également ma mise en page dans d'autres activités
MainActivity
, donc je ne peux pas simplement coder une flèche en dur.Ce qui a fonctionné pour moi:
private void setupActionBar() { LinearLayout root = (LinearLayout)findViewById(android.R.id.list).getParent().getParent().getParent(); Toolbar toolbar = (Toolbar)LayoutInflater.from(this).inflate(R.layout.app_bar, root, false); root.addView(toolbar, 0); setSupportActionBar(toolbar); ActionBar ab = getSupportActionBar(); ab.setDisplayHomeAsUpEnabled(true); }
la source
J'ai eu le même problème. essayez simplement de changer le thème de l'activité en celui qui contient une ActionBar. l'ajout de la ligne suivante dans la balise d'activité de SettingsActivity a fonctionné pour moi:
android:theme="Theme.AppCompat.DayNight.DarkActionBar"
la source
Un moyen facile que j'ai compris est de passer outre:
@android:style/Theme.Material.Light.DarkActionBar
Dans votre style:
<style name="SettingsTheme" parent="@android:style/Theme.Material.Light.DarkActionBar"> <item name="android:colorPrimary">@color/sunshine_blue</item> <item name="android:colorPrimaryDark">@color/sunshine_dark_blue</item> </style>
la source