Après avoir mis à niveau vers la bibliothèque de support technique v21, ma barre d’action dans ma PreferenceActivity
a disparu.
Ai-je oublié des attributs dans mon thème pour l'activer à nouveau? J'ai eu un problème similaire avec un ActionBar noir .
J'ai également essayé d'ajouter un peu de hack en ajoutant Toolbar
à la disposition racine, mais cela ne fonctionnait pas comme prévu.
S'il vous plaît trouver le repo GitHub: ici
Très similaire à votre propre code mais ajouté XML pour permettre le titre du jeu:
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 :
Comme souligné ici , les périphériques Gingerbread retournent une exception NullPointerException sur cette ligne:
LinearLayout root = (LinearLayout)findViewById(Android.R.id.list).getParent().getParent().getParent();
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!
UPDATE 2: SOLUTION DE CONTOURNEMENT
Comme indiqué dans de nombreuses notes de dev, PreferenceActivity
ne prend pas en charge la coloration des éléments. Toutefois, en utilisant quelques classes internes, vous POUVEZ y parvenir. C'est jusqu'à ce que ces classes sont supprimées. (Fonctionne avec appCompat support-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;
Puis substituez la méthode 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.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 a introduit de nouveaux éléments coloré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. Suivez plutôt ceci (en remplaçant toujours 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;
}
ECRANS DE PREFERENCE NEDES
De nombreuses personnes rencontrent des problèmes pour inclure la barre d'outils dans des <PreferenceScreen />
s imbriqués. Cependant, j'ai trouvé une solution! - Après beaucoup d'essais et d'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 PreferenceScreen
pose un problème est qu’elle repose sur une boîte de dialogue d’emballage, nous devons donc capturer la disposition de la boîte de dialogue pour y ajouter la barre d’outils.
De par sa conception, l'importation de Toolbar
ne permet pas l'élévation ni l'ombrage dans les périphériques antérieurs à la v21, donc si vous souhaitez avoir une élévation sur votre Toolbar
, vous devez l'envelopper dans une AppBarLayout
:
`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 fichier build.gradle
:
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'
J'ai enquêté sur le problème de chevauchement signalé et je ne peux pas le reproduire.
Le code complet utilisé ci-dessus produit les éléments suivants:
Si je manque quelque chose s'il vous plaît faites le moi savoir via ce repo et je vais enquêter.
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();
}}
PreferenceFragment:
public class SettingsFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings_preferences);
}}
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 mon 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" />
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 factuelle à partir de la bibliothèque de support. Voici un exemple de code à 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;
}
}
Salut, je ne suis pas si vous avez toujours ce problème. Mais je pense que je posterai ce que j'ai fait pour résoudre ce problème et 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 doit hériter de ActionBarActivity. Donc, voici votre problème.
2) Les étapes que j'ai l'habitude de résoudre sont les suivantes:
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é!
J'ai eu le même problème. essayez simplement de changer le thème de l’activité en celui qui contient un ActionBar. l'ajout de la ligne suivante dans la balise d'activité de SettingsActivity m'a été utile:
Android:theme="Theme.AppCompat.DayNight.DarkActionBar"
J'ai fait quelque chose de similaire à la question acceptée, mais j'utilise ma mise en page dans d'autres activités également (MainActivity
également), aussi je ne peux pas simplement coder en dur une flèche.
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);
}