为什么在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_width
和android: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" [...] />