在保持其样式设置的同时更改Android复合控件的启用状态

时间:2014-04-21 16:32:48

标签: android composite-controls

我有一个自定义按钮,我已将其实现为复合控件,它由以下部分组成:

  • 根目录下的FrameLayout,我用@android设计样式:style / Widget.Holo.Button,以便看起来像按钮一样;
  • 两个TextView作为上述FrameLayout的子项,配置了duplicateParentState = true,以便在我将FrameLayout上的enabled设置为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);
  }
}

如果我理解正确,当使用此控件时,构造的层次结构将是(括号表示定义View的位置):

FrameLayout (Java) -> FrameLayout (XML) -> 2x TextViews (XML)

我希望能够通过获取对按钮的引用并设置enabled属性来切换是否启用了自定义按钮,如下所示:

CustomButton button = (CustomButton)findViewById(R.id.button);
button.setEnabled(false);

然而,这不起作用,因为XML中定义的FrameLayout不继承其父级属性,因此按钮继续显示为已启用。

我尝试将duplicateParentState = true添加到XML中定义的FrameLayout,但在这种情况下,我的样式属性被覆盖/继承,控件看起来不再像按钮了。

我也尝试过使用merge标签并以编程方式设置样式,但据我所知,无法以编程方式设置View样式。

到目前为止,我的解决方法是覆盖CustomButton上的setEnabled()方法,如下所示:

public void setEnabled(boolean enabled) {
    super.setEnabled(enabled);
    findViewById(R.id.button_rootLayout).setEnabled(enabled);
}

这有效但我现在必须为我想要以编程方式修改的每个属性执行此操作,并且我在注册OnClickListeners时遇到类似的问题。

有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

怎么样:

public void setEnabled(boolean enabled) {
    super.setEnabled(enabled);
    setClickable(enabled);
}

这就是我最终要做的事情。