Por qué es tan complejo establecer el estilo del código en Android

Si desea establecer el estilo de un Botón que crea desde el código, debe hacer algo como esto;

Button btn = new Button (mActivity, null, R.attr.someattribute); 

en attrs.xml, configura una referencia

  

En styles.xml, defines un tema

   @style/someStyle   

Que lates en styles.xml se define como por ejemplo

  2px fill_parent @drawable/actionbar_compat_separator  

Esto funciona, y esto es, según mi entender, la forma de establecer un estilo en una Vista desde el código en Android. Esto parece demasiado complejo. El tercer argumento del constructor del botón podría haber aceptado fácilmente un ID de estilo R.style.XXX

¿Alguien puede explicar por qué se necesita esta complejidad adicional?

Tiene que ver con los patrones recomendados dentro de Android en torno a usar Views. Este no es el enfoque previsto para lo que parece que estás tratando de hacer. Primero explicaré para qué es este mecanismo y luego sugeriré un enfoque para su aplicación.

El tercer argumento para ver constructores que toma un recurso attr generalmente se usa cuando se implementan subclases de vista y, como se ha mostrado, le permite especificar un atributo de tema para usar como referencia al estilo predeterminado de la vista. Si tuviera un tipo especial de botón llamado AwesomeButton, podría implementar sus constructores de esta manera:

 public class AwesomeButton extends Button { public AwesomeButton(Context context) { this(context, null); } public AwesomeButton(Context context, AttributeSet attrs) { this(context, attrs, R.attr.awesomeButtonStyle); } public AwesomeButton(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr) { final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AwesomeButton, defStyleAttr, 0); // Read AwesomeButton-specific style attributes from a a.recycle(); } // More code } 

Cuando LayoutInflater de Android infla las vistas usa el constructor de dos argumentos con los argumentos (Context, AttributeSet) . La constante R.attr se pasa a la versión de 3 argumentos y luego al constructor de 3 argumentos de Button en la super llamada. Esto significa que Button leerá información de estilo predeterminada para las cosas que encapsula desde el estilo predeterminado de AwesomeButton como se especifica en su tema. Algunas Vistas dentro de Android difieren de su superclase solo en el estilo predeterminado que usan. ( Button es en realidad uno de estos).

Especifique android:layout_width y android:layout_height en su estilo, pero esto puede ser problemático. LayoutParams (cualquier atributo que comience con layout_ ) son específicos de la vista principal, no de la vista en la que aparecen. Esta es la razón por la que siempre pasa la vista padre prevista como el segundo parámetro a LayoutInflater#inflate – le dice al inflater qué clase debería ser responsable de interpretar los LayoutParams . Si omite esto, a menudo encontrará que sus LayoutParams no se comportan como espera y, a menudo, se ignoran por completo. Por convención, no ponemos LayoutParams en estilos aunque en algunos casos especiales funciona.

Parece que estás tratando de usar un estilo como una especie de plantilla. ¿Hay alguna razón para no usar un recurso de diseño para esto y especificar el estilo allí?

 final LayoutInflater inflater = LayoutInflater.from(mActivity); Button btn = (Button) inflater.inflate(R.layout.styled_button, parentView, false); 

res / layout / styled_button.xml: