我有一个自定义按钮,我已将其实现为复合控件,该控件由以下部分组成:
- 根处的 FrameLayout,我使用 @android:style/Widget.Holo.Button 对其进行了样式设置,以便看起来和行为像一个按钮;
- 作为上述 FrameLayout 的子项的两个 TextView,配置为 duplicateParentState=true,因此如果我将 FrameLayout 上的启用设置为 false,它们将显示为禁用。
修剪后的 XML 如下所示:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
style="@android:style/Widget.Holo.Button"
android:id="@+id/layout_button">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="PLACEHOLDER"
android:layout_gravity="center_horizontal|top"
android:duplicateParentState="true"
android:id="@+id/text_button1"
android:textSize="24sp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="PLACEHOLDER"
android:layout_gravity="center_horizontal|bottom"
android:duplicateParentState="true"
android:id="@+id/text_button2"
android:textSize="12sp"/>
</FrameLayout>
除了复合控件的 XML 布局,我还创建了一个 Java 实现,如 Android 文档中所述,它看起来像这样:
public class CustomButton extends FrameLayout {
public CustomButton (Context context, AttributeSet attrs) {
super(context, attrs);
LayoutInflater layoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
layoutInflater.inflate(R.layout.control_custombutton, this, true);
}
}
如果我理解正确,当使用此控件时,构造的层次结构将是(括号指示视图的定义位置):
FrameLayout (Java) -> FrameLayout (XML) -> 2x TextViews (XML)
我希望能够通过获取对按钮的引用并设置 enabled 属性来切换我的自定义按钮是否启用,如下所示:
CustomButton button = (CustomButton)findViewById(R.id.button);
button.setEnabled(false);
但是,这不起作用,因为 XML 中定义的 FrameLayout 不继承其父级的属性,因此按钮继续显示为已启用。
我尝试将 duplicateParentState=true 添加到 XML 中定义的 FrameLayout 中,但在这种情况下,我的样式属性被覆盖/继承,并且控件看起来不再像按钮了。
我也尝试过使用合并标记并以编程方式设置样式,但据我所知,无法以编程方式设置视图样式。
到目前为止,我的解决方法是覆盖 CustomButton 上的 setEnabled() 方法,如下所示:
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
findViewById(R.id.button_rootLayout).setEnabled(enabled);
}
这可行,但我现在必须对我想以编程方式修改的每个属性执行此操作,并且我在注册 OnClickListeners 时遇到了类似的问题。
有没有更好的办法?