gpt4 book ai didi

android - 如何在 XML 中定义一个特定 fragment 实例的样式/主题?

转载 作者:行者123 更新时间:2023-12-02 14:11:55 30 4
gpt4 key购买 nike

我在我的应用程序中创建了一个 UI 组件,该组件在多个地方使用(有些亮,有些暗),并且需要是 lifecycle-aware ,所以我将其转换为 fragment 。我专门使用 <fragment> 实例化该 fragment 我的 Activity 的 XML 布局文件中的标签。

我正在努力寻找一种方法,使 fragment 能够以适合其父元素设置的背景的颜色呈现自己的控件和文本。目前,无论我在父 View 或<fragment>上设置什么主题或样式,标签本身, fragment 控件显示为浅色背景:

the fragment as rendered on a light background the fragment as rendered on a dark background

我尝试过设置 android:theme关于<fragment>两者 @style/ThemeOverlay.AppCompat.Dark@style/ThemeOverlay.AppCompat.Dark.ActionBar试图让文本在深色背景上呈现浅色,但没有成功。

我不想将这种颜色切换编程到 fragment 本身中,因为我觉得主题/样式框架肯定能够处理这个问题。

理想情况下,我还可以在稍后阶段将图标合并到此 fragment 中,其颜色与文本相匹配。不过,我现在的首要任务是获得正确的文本颜色。

告诉 fragment 的一个特定实例的正确方法是什么,“您处于深色背景而不是浅色背景”,或者“您需要以浅色而不是深色背景渲染文本和控件” ,”并相应地渲染?

更新

我已经posted an answer这是通过在 <fragment> 上实现自定义属性来实现的。标签并在我的 fragment 代码中对其进行初始化。

之前的更新

Chris Banes' article on Theme vs. Style状态:

One thing to note is that android:theme in Lollipop propogates to all children declared in the layout:

<LinearLayout
android:theme="@android:style/ThemeOverlay.Material.Dark">

<!-- Anything here will also have a dark theme -->

</LinearLayout>

Your children can set their own theme if needed.

在我使用 fragment 的情况下,这显然不会发生 - 似乎 android:theme <fragment> 的属性XML 中的标签在通货膨胀期间根本不被考虑,但应该被考虑。

我的 fragment 的onCreateView方法相当标准:

@Override
public View onCreateView(
@NonNull LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState
) {
return inflater.inflate(R.layout.fragment_task_search, container, false);
}

我想要么 container没有开始获得主题,或者充气器没有将该信息“附加”到充气的 subview 中。我对 Android 开发不够精通,无法确定是哪种情况(如果有的话)。

最佳答案

通过在<fragment>上的自定义属性中显式指定父容器的主题,我已经达到了预期的效果。标签,并在 fragment 初始化期间手动读取它。

使用 <fragment> 的 XML 布局文件

  1. 确保 XML 的根元素具有以下 xmlns:app属性:

    xmlns:app="http://schemas.android.com/apk/res-auto"
  2. 添加自定义属性 app:customTheme<fragment>标签:

    <fragment
    android:name="net.alexpeters.myapp.TaskSearchFragment"
    app:customTheme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />

属性 XML 文件 values/attrs.xml

添加 declare-styleable元素如下所示:

    <?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- ↓↓↓ -->
<declare-styleable name="TaskSearchFragment">
<attr name="customTheme" format="reference" />
</declare-styleable>
<!-- ↑↑↑ -->
</resources>

Fragment子类

  1. 添加一个实例变量来保存自定义主题 ID:

    private @StyleRes int themeResId;
  2. 添加一个常量来处理没有传入自定义主题的情况:

    private static final int NO_CUSTOM_THEME = 0;
  3. 覆盖 onInflate方法如下:

    @Override
    public void onInflate(
    @NonNull Context context,
    AttributeSet attrs,
    Bundle savedInstanceState
    ) {
    super.onInflate(context, attrs, savedInstanceState);
    TypedArray a = context.obtainStyledAttributes(
    attrs,
    R.styleable.TaskSearchFragment
    );
    themeResId = a.getResourceId(
    R.styleable.TaskSearchFragment_customTheme,
    NO_CUSTOM_THEME
    );
    a.recycle();
    }
  4. onCreateView 添加一些逻辑将自定义主题引用注入(inject)充气器的方法:

    @Nullable
    @Override
    public View onCreateView(
    @NonNull LayoutInflater inflater,
    @Nullable ViewGroup container,
    @Nullable Bundle savedInstanceState
    ) {
    // ↓↓↓
    if (themeResId != NO_CUSTOM_THEME) {
    inflater = inflater.cloneInContext(
    new ContextThemeWrapper(getActivity(), themeResId)
    );
    }
    // ↑↑↑
    return inflater.inflate(R.layout.fragment_task_search, container, false);
    }

我更愿意以某种方式推断父容器的主题,但我不知道这是否可能。

如果做不到这一点,我更愿意使用标准属性(即 android:theme )而不是自定义属性,但我也不知道这是否可行。

关于android - 如何在 XML 中定义一个特定 fragment 实例的样式/主题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47285977/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com