为什么在Android中设置代码风格太复杂了

如果你想设置你从代码创build的Button的样式,你必须做这样的事情;

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

在attrs.xml中,你设置了一个引用

 <attr name="someStyleRef" format="reference"/> 

在styles.xml中,您定义了一个主题

 <resources> <style name="Theme.SomeTheme" parent="android:style/Theme.Black"> <item name="someStyleRef">@style/someStyle</item> </style> </resources> 

styles.xml中的lates被定义为例子

 <style name="someStyle"> <item name="android:layout_width">2px</item> <item name="android:layout_height">fill_parent</item> <item name="android:background">@drawable/actionbar_compat_separator</item> </style> 

这是有效的,根据我的理解,这是从Android中的代码设置视图风格的方式。 这似乎过于复杂。 button的第三个构造函数Argument可以很容易地接受一个样式ID R.style.XXX

任何人都可以解释为什么这需要额外的复杂性

它与Android中围绕使用视图的鼓励模式有关。 这不是你想要做的目标。 首先我会解释这个机制是什么,然后为你的应用程序提供一个方法。

在实现View子类时,通常使用View构造函数的第三个参数来获取attr资源,并且如您所示,让您指定一个主题属性作为对View默认样式的引用。 如果你有一个特殊的叫做AwesomeButton的button,你可以像这样实现它的构造函数:

 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 } 

当Android的LayoutInflater膨胀视图时,它使用具有参数(Context, AttributeSet)的2参数构造函数。 R.attr常量被传递给3参数版本,然后在super调用中传递给Button的3参数构造函数。 这意味着Button会根据主题中指定的AwesomeButton的默认样式来读取默认样式信息。 Android中的某些视图与其超类的区别仅在于它们使用的默认样式。 ( Button实际上是其中之一。)

你在你的风格中指定了android:layout_widthandroid:layout_height ,但这可能会有问题。 LayoutParams (以layout_开头的任何属性)都是父视图所特有的,而不是它们出现的视图。 这就是为什么你总是将想要的父视图传递给LayoutInflater#inflate的第二个参数 – 它告诉LayoutInflater#inflate哪个类应该负责解释LayoutParams 。 如果你跳过这个,你会经常发现你的LayoutParams不像你期望的那样行事,经常被直接忽略。 按照惯例,即使在某些特殊情况下,它也不LayoutParams样式放在LayoutParams中。

它看起来像你试图使用一种风格作为一种模板。 是否有一个不使用布局资源的原因,并指定在那里的样式?

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

RES /布局/ styled_button.xml:

 <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/my_button_background" [...] />