Comment append la barre d’action de la bibliothèque de support dans PreferenceActivity?

La compatibilité de la barre d’action a été ajoutée à la bibliothèque de support, révision 18. Elle dispose désormais de la classe ActionBarActivity pour créer des activités avec la barre d’action sur les anciennes versions d’Android.

Existe-t-il un moyen d’append la barre d’action de la bibliothèque de support dans PreferenceActivity ?

Auparavant, j’ai utilisé ActionBarSherlock et il a SherlockPreferenceActivity .

    EDIT: Dans appcompat-v7 22.1.0, Google a ajouté la classe abstraite AppCompatDelegate en tant que délégué que vous pouvez utiliser pour étendre la prise en charge d’AppCompat à n’importe quelle activité.

    Utilisez-le comme ceci:

     ... 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; } } 

    Plus de piratage. Code tiré de AppCompatPreferenceActivity.java .

    Il n’y a actuellement aucun moyen de réaliser avec AppCompat. J’ai ouvert un bug en interne.

    J’ai réussi à créer une solution similaire à celle utilisée par Google Play Store. Lien vers la réponse originale

    S’il vous plaît trouver le GitHub Repo: Ici


    Très similaire à votre propre code, mais ajout de XML pour autoriser le titre:

    Continuer à utiliser PreferenceActivity :

    settings_toolbar.xml :

     < ?xml version="1.0" encoding="utf-8"?>  

    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 :

    Exemple


    UPDATE (Compatibilité Gingerbread):

    Comme indiqué ici , les périphériques Gingerbread renvoient 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.ICE_CREAM_SANDWICH) { 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().resolveAtsortingbute(R.attr.actionBarSize, tv, true)) { height = TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMesortingcs()); }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 me le fait savoir!


    MISE À JOUR 2: TINTING WORKAROUND

    Comme souligné dans de nombreuses notes de dev, PreferenceActivity ne prend pas en charge la coloration 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 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; 

    onCreateView ensuite la méthode onCreateView :

     @Override public View onCreateView(Ssortingng name, Context context, AtsortingbuteSet 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:

    exemple 2


    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 onCreateView ):

     @Override public View onCreateView(Ssortingng name, Context context, AtsortingbuteSet 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 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 NESTE

    Beaucoup de personnes rencontrent des problèmes pour inclure la barre d'outils dans

    nested, mais 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().resolveAtsortingbute(R.attr.actionBarSize, tv, true)) { height = TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMesortingcs()); }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 est si pénible est qu'elles sont basées sur une boîte de dialog d'encapsulation. Nous devons donc capturer la disposition de la boîte de dialog pour y append la barre d'outils.


    Toolbar Shadow

    Par nature, l’importation de la Toolbar ne permet pas l’élévation et l’observation dans les périphériques pré-v21, donc si vous souhaitez avoir une élévation dans votre Toolbar d’ Toolbar vous devez l’emballer dans un AppBarLayout :

    `settings_toolbar.xml:

        

    Sans oublier d’append la bibliothèque Add Support Design en tant que dépendance dans le fichier build.gradle :

     comstack 'com.android.support:support-v4:22.2.0' comstack 'com.android.support:appcompat-v7:22.2.0' comstack 'com.android.support:design:22.2.0' 

    Android 6.0

    J'ai enquêté sur le problème de chevauchement signalé et je ne peux pas reproduire le problème.

    Le code complet utilisé ci-dessus produit les éléments suivants:

    entrer la description de l'image ici

    Si quelque chose me manque, faites-le moi savoir via ce repo et je vais enquêter.

    Vous avez trouvé une implémentation PreferenceFragment basée sur le fragment support-v4:

    https://github.com/kolavar/android-support-v4-preferencefragment

    Edit: Je viens de le tester et son fonctionnement est génial!

    L’intégration de PreferenceActivity avec ABC n’est pas possible, du moins pour moi. J’ai essayé les deux possibilités que j’ai pu trouver mais aucune n’a fonctionné:

    Option 1:

    ActionBarPreferenceActivity étend PreferenceActivity . Lorsque vous faites cela, vous êtes limité par ActionBarActivityDelegate.createDelegate(ActionBarActivity activity) . Vous devez également implémenter ActionBar.Callbacks qui n’est pas accessible

    Option 2:

    ActionBarPreferenceActivity étend ActionBarActivity . Cette approche nécessite de réécrire une toute nouvelle PreferenceActivity , PreferenceManager et peut-être PreferenceFragment ce qui signifie que vous devez avoir access à des classes cachées comme com.android.internal.util.XmlUtils La solution ne peut venir que des développeurs Google qui implémentent toute activité.

    Si vous avez vraiment besoin d’une activité de préférence, mon conseil pour le moment est ActionBarSherlock .

    Cependant, j’ai réussi à le mettre en œuvre ici .

    Contexte du problème:

    L’OP veut savoir comment placer MenuItem dans le ActionBar d’ ActionBar de PreferenceActivity pour pre-Honeycomb, car la bibliothèque de support d’Android a un bogue qui ne permet pas cela.

    Ma solution:

    J’ai trouvé une méthode beaucoup plus propre que celle proposée pour atteindre la cible (et l’a trouvée dans les documents Android ):

    android:parentActivityName

    Le nom de classe du parent logique de l’activité. Le nom ici doit correspondre au nom de classe atsortingbué à l’atsortingbut android: name de l’élément correspondant.

    Le système lit cet atsortingbut pour déterminer quelle activité doit être démarrée lorsque l’utilisation appuie sur le bouton Haut de la barre d’action. Le système peut également utiliser ces informations pour synthétiser une stack d’activités avec TaskStackBuilder.

    Pour prendre en charge les niveaux d’API 4 à 16, vous pouvez également déclarer l’activité parente avec un élément qui spécifie une valeur pour “android.support.PARENT_ACTIVITY”. Par exemple:

         

    Faites maintenant ce que vous feriez normalement dans votre onOptionsItemSelected() . Comme il fait partie d’Android Docs, il n’a pas d’effets secondaires.

    Heureux codage 🙂

    Mettre à jour:

    Cette solution ne fonctionne plus si vous ciblez Lollipop. Si vous utilisez AppCompat, cette réponse est ce que vous devez rechercher.

    J’ai pu obtenir android.app.Actionbar en utilisant getActionBar() . Il a renvoyé une valeur nulle au début … puis je suis allé au manifeste et j’ai changé le thème pour:

     android:theme="@style/Theme.AppCompat" 

    Ensuite, j’ai pu avoir à nouveau la barre d’action. Je suppose que cela ne fonctionnera que pour certains niveaux de construction. Vous pouvez donc vérifier le numéro de build ou vérifier si la valeur renvoyée est nulle.

    Cela me conviendra car l’application sur laquelle je travaille concerne ICS/4.0 +.

    Maintenant, la réponse officielle à ce problème a été publiée. Il s’agit de la bibliothèque de prise en charge des préférences v7 / v14 .

    Voir Comment utiliser la bibliothèque v7 / v14 Preference Support? pour la discussion comment l’utiliser.