support desing android android-support-library preferenceactivity android-5.0-lollipop

desing - com.android.support:support-v4 28



Sin ActionBar en PreferenceActivity después de la actualización a Support Library v21 (6)

Encuentre el GitHub Repo: Here

Muy similar a su propio código, pero agregó xml para permitir el título del conjunto:

Continuar usando 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 :

ACTUALIZACIÓN (Gingerbread Compatibility):

Como se señala here , los dispositivos Gingerbread devuelven NullPointerException en esta línea:

LinearLayout root = (LinearLayout)findViewById(android.R.id.list).getParent().getParent().getParent();

FIJAR:

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

Cualquier problema con lo anterior, hágamelo saber!

ACTUALIZACIÓN 2: TINTING WORKAROUND

Como se señala en muchas notas de desarrollo, PreferenceActivity no es compatible con el tinte de elementos, sin embargo, al utilizar algunas clases internas, PUEDE lograrlo. Eso es hasta que se eliminen estas clases. (Funciona con appCompat support-v7 v21.0.3).

Agregue las siguientes importaciones:

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;

Luego, anule el método 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

AppCompat 22.1 introdujo nuevos elementos tintados, lo que significa que ya no es necesario utilizar las clases internas para lograr el mismo efecto que la última actualización. En su lugar, siga esto (sigue anulando en 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; }

PANTALLAS DE PREFERENCIA ANIDAS

Mucha gente tiene problemas para incluir la barra de herramientas en <PreferenceScreen /> anidado, sin embargo, ¡he encontrado una solución! - ¡Después de mucho ensayo y error!

Agregue lo siguiente a su 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(); } }); }

El motivo por el que PreferenceScreen es tan molesto es porque se basan en un cuadro de diálogo contenedor, por lo que debemos capturar el diseño del cuadro de diálogo para agregarle la barra de herramientas.

Barra de herramientas Shadow

Por diseño, la importación de la Toolbar no permite la elevación y el sombreado en dispositivos anteriores a v21, por lo que si desea tener elevación en su Toolbar , debe envolverlo en un 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>

Sin olvidarse de agregar agregar la biblioteca Design Support como una dependencia en el archivo 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''

Android 6.0

Investigué el problema superpuesto y no puedo reproducir el problema.

El código completo en uso como arriba produce lo siguiente:

Si me falta algo, házmelo saber a través de Here e investigaré.

Después de actualizar a la biblioteca de soporte v21 mi ActionBar en mi actividad de PreferenceActivity se ha ido.

¿Perdí algunos atributos en mi tema para activarlo de nuevo? Tuve algunos problemas similares con un ActionBar negro .

También traté de agregar un poco de hackish agregando una Toolbar de Toolbar al diseño de la raíz, pero eso no funcionó como se esperaba.


Hola, no, si todavía tienes este problema. Pero creo que publicaré lo que hice para resolver esto y espero que ayude a alguien.

1) En primer lugar, es posible que haya notado que PreferenceActivity amplía ListActivity, que a su vez se extiende desde Activity.

De acuerdo con los comentarios en el blog de desarrolladores ( http://android-developers.blogspot.com/2014/10/appcompat-v21-material-design-for-pre.html ), para usar v21 todas sus actividades deben heredarse de ActionBarActivity . Entonces está tu problema.

2) Los pasos que solía resolver son:

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.

Esto debería resolverlo.

¡Aclamaciones!


Terminé agregando la barra de herramientas con este código 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(); } });

Aquí está mi 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" />


Una forma fácil que descubrí es que prevalece:

@android:style/Theme.Material.Light.DarkActionBar

En tu estilo:

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


Una mejor solución que "rodar tu propia" barra de acción es usar la clase AppCompatDelegate , que te permite incorporar una barra de acciones real de la biblioteca de soporte. Aquí hay un código de ejemplo para usarlo, tomado de la respuesta de Ľubomír Kučera a esta pregunta .

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


Use AppCompatActivity & PreferenceFragment para resolver el problema:

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