android - style - Aplique tint a los widgets de PreferenceActivity con AppCompat v21
spinner theme android (5)
Estoy usando CheckboxPreference en una PreferenceActivity y un tema AppCompat de la biblioteca de soporte v21. Como ya sabe, con esta última biblioteca, los widgets como las casillas de verificación, los textos de edición, los botones de radio, etc. están teñidos con el color secundario definido en el tema. En la pantalla de preferencias, el texto está en el color correcto como se especifica en mi tema, pero las casillas de verificación y el texto de edición no lo están. Parece que cuando la instancia de CheckboxPreference crea el widget, no le aplica mi tema.
Botones de radio en un diseño normal, teñidos:
captura de pantalla 1 http://i59.tinypic.com/2qv9stj.png
Checkbox de CheckboxPreference, no teñido:
captura de pantalla 2 http://i61.tinypic.com/91bcly.png
Estoy usando como el tema principal Theme.AppCompat.Light.NoActionBar
. Esto le sucede a cada subclase de Preference con un widget, como EditTextPreference para decir uno, donde EditText tiene una línea inferior negra, en lugar de una línea teñida. ¿Cómo puedo aplicar el tinte a los widgets que se muestran en las subclases de preferencias?
ACTUALIZACIÓN : el tintado no se aplica porque PreferenceActivity extiende el marco de actividad. En el caso de trabajo, estoy usando una ActionBarActivity de la biblioteca de soporte. Ahora la pregunta es: ¿por qué?
Hasta ahora, mi propia solución (triste) era crear desde cero mis propios dibujables de casillas de verificación, utilizando los colores con los que la casilla de verificación debería haberse teñido en primer lugar.
En styles.xml:
<?xml version="1.0" encoding="utf-8"?>
<style name="AppThemeBase" parent="Theme.AppCompat.Light.NoActionBar">
...
<!-- edit the checkbox appearance -->
<item name="android:listChoiceIndicatorMultiple">@drawable/my_checkbox</item>
...
</style>
drawable / my_checkbox.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:drawable="@drawable/checkbox_on" />
<item android:drawable="@drawable/checkbox_off" />
</selector>
checkbox_on" and
checkbox_off` son los elementos dibujables PNG para los estados seleccionados y no seleccionados, obviamente uno para cada densidad de pantalla. Si le importa la consistencia de la dimensión, la dimensión de la línea de base (MDPI) de los elementos dibujables debe ser de 32 píxeles de valor completo y 18px cuadrado óptico.
La solución dada por Tamás Szincsák funciona muy bien, pero debería actualizarse, si se utiliza appcompat-v7: 22.1.1, de la siguiente manera:
las importaciones deben ser cambiadas a
import android.support.v7.widget.AppCompatCheckBox;
import android.support.v7.widget.AppCompatCheckedTextView;
import android.support.v7.widget.AppCompatEditText;
import android.support.v7.widget.AppCompatRadioButton;
import android.support.v7.widget.AppCompatSpinner;
Y, respectivamente, el interruptor debe ser
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);
}
Sé que esta pregunta es algo antigua, pero quería dejar una solución para superar este problema que ha experimentado. En primer lugar, me gustaría decir que la Actividad de PreferenceActivity
es una reliquia de los tiempos anteriores al panal, así que no espere que Google tiñe sus Widgets en este subconjunto de Actividad realmente muy antiguo.
En lugar de PreferenceActivity, debe usar PreferenceFragments
que se incluirán en una Activity
(preferiblemente una ActionbarActivity
si desea que se ActionbarActivity
los widgets).
Siguiendo un ejemplo de código bastante básico, cómo debería verse tu Actividad de configuración.
Ejemplo
public class MySettings extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.settings_activity);
getFragmentManager().beginTransaction()
.replace(R.id.container, new MyPreferenceFragment()).commit();
}
public static class MyPreferenceFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences_file);
}
}
}
Nota: En este ejemplo, he usado un FrameLayout como mi contenedor para los PreferenceFragments
Resultado:
Así que, como puede ver, sus widgets se colorAccent
correctamente de acuerdo con el colorAccent
que haya establecido.
Más sobre PreferenceFragments en developer.android.com (haga clic) .
Si está utilizando AppCompat, entonces use los elementos de compatibilidad de aplicaciones en su archivo style.xml.
Por ejemplo, use:
<style name="AppTheme" parent="Theme.AppCompat.Light">
<item name="colorPrimary">@color/primary</item>
<item name="colorPrimaryDark">@color/primary_dark</item>
<item name="colorAccent">@color/accent</item>
</style>
NO (nota "android:"):
<style name="AppTheme" parent="Theme.AppCompat.Light">
<item name="android:colorPrimary">@color/primary</item>
<item name="android:colorPrimaryDark">@color/primary_dark</item>
<item name="android:colorAccent">@color/accent</item>
</style>
Esto solucionó el problema para mí.
Edición : a partir de AppCompat 22.1, cualquier actividad puede ser temática usando AppCompatDelegate . El nombre de las clases de vista teñida también cambió de v7.internal.widget.TintXYZ
a v7.widget.AppCompatXYZ
. La respuesta a continuación es para AppCompat 22.0 y versiones posteriores.
También encontré este problema y lo resolví simplemente copiando el código relacionado con el tintado de widgets de ActionBarActivity. Una desventaja de esta solución es que se basa en clases internas que podrían cambiar o dejar de estar disponibles en el futuro.
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;
public class MyActivity extends PreferenceActivity {
@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;
}
}
Esto funciona porque el servicio onCreateView llama a onCreateView para cada vista que se está inflando desde un recurso de diseño, lo que permite que la actividad anule las clases que se crean instancias. Asegúrese de que el tema de la actividad esté establecido en Theme.AppCompat. (o descendientes) en el manifiesto.
Vea ActionBarActivity.java y ActionBarActivityDelegateBase.java para el código original.