以编程方式创建的视图不继承主题

Views created progmatically aren't inheriting theme

我正在尝试实用地创建视图,然后将其添加到我的 activity。这一点工作正常,但是视图组的主题没有被我的新视图继承

我的主题:

<style name="CustomButtonTheme" parent="@style/Widget.AppCompat.Button">
  <item name="android:textColor">#FF0000</item>
  <item name="android:background">#00FF00</item>
</style>

我的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/buttonArea"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:theme="@style/CustomButtonTheme">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This button inherits CustomButtonTheme" />
</LinearLayout>

Java代码

AppCompatButton button = new AppCompatButton(getContext());
button.setText("This button does not inherit CustomButtonTheme");

LinearLayout buttonArea = findViewById<LinearLayout>(R.id.buttonArea);
buttonArea.addView(button);

布局中的 android:theme 属性仅在 inflation 期间有效,并且仅对该特定子树有效。它不会应用于 Activity 的整体主题。

尽管如此,该属性所做的只是导致 LayoutInflater 将其当前 Context 与指定主题包装在 ContextThemeWrapper 中。我们可以自己做一些类似的事情,只是为了说明基本用法:

ContextThemeWrapper wrapper = new ContextThemeWrapper(getContext(), R.style.CustomButtonTheme);
AppCompatButton button = new AppCompatButton(wrapper);

然而,这已经为我们完成了,基本上,当 LayoutInflater 在内部为那个 android:theme 属性创建了一个 ContextThemeWrapper 时。 ContextThemeWrapper 是创建 LinearLayoutContext,所以我们可以简单地使用它的 Context 来实例化我们的 AppCompatButton:

AppCompatButton button = new AppCompatButton(buttonArea.getContext());

正如 OP 指出的那样,这有一个额外的好处,即可以在几乎所有类似的设置中工作,而不必知道所需的确切主题。