Изменение включенного состояния композитного элемента управления Android при сохранении настроек стиля

У меня есть пользовательская кнопка, которую я реализовал как составной элемент управления, который состоит из:

  • FrameLayout в корне, который я создал с помощью @android:style/Widget.Holo.Button, чтобы он выглядел и действовал как кнопка;
  • Два TextView в качестве дочерних элементов вышеупомянутого FrameLayout, настроенного с 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);

Однако это не работает, так как FrameLayout, определенный в XML, не наследует свойства своего родителя, и поэтому кнопка продолжает отображаться как активированная.

Я попытался добавить duplicateParentState = true к FrameLayout, определенному в XML, но в этом случае мой атрибут стиля перезаписывается / наследуется, и элемент управления больше не выглядит как кнопка.

Я также пытался использовать тег слияния и устанавливать стиль программно, но насколько я могу судить, невозможно установить стили просмотра программно.

До сих пор мой обходной путь состоял в том, чтобы переписать метод setEnabled() в CustomButton следующим образом:

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

Это работает, но теперь я должен сделать это для каждого свойства, которое я хочу изменить программно, и у меня есть похожие проблемы с регистрацией OnClickListeners.

Есть ли способ лучше?

1 ответ

Как насчет:

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

Это то, что я в итоге сделал.

Другие вопросы по тегам