Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/193.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何定义一个特定的片段实例';XML中的s样式/主题?_Android_Android Layout_Android Fragments_Android Theme_Android Styles - Fatal编程技术网

Android 如何定义一个特定的片段实例';XML中的s样式/主题?

Android 如何定义一个特定的片段实例';XML中的s样式/主题?,android,android-layout,android-fragments,android-theme,android-styles,Android,Android Layout,Android Fragments,Android Theme,Android Styles,我已经在我的应用程序中创建了一个UI组件,可以在多个地方使用(有些亮,有些暗),并且需要使用它,所以我将它转换为一个新的应用程序。我在活动的XML布局文件中专门使用标记实例化这个片段 我正在努力寻找一种方法,使片段能够按照父元素设置的适合其背景的颜色呈现自己的控件和文本。目前,无论我在父视图或标记本身上设置了什么主题或样式,片段控件都会显示为浅背景: 我尝试将上的android:theme设置为@style/ThemeOverlay.AppCompat.Dark和@style/ThemeOv

我已经在我的应用程序中创建了一个UI组件,可以在多个地方使用(有些亮,有些暗),并且需要使用它,所以我将它转换为一个新的应用程序。我在活动的XML布局文件中专门使用
标记实例化这个片段

我正在努力寻找一种方法,使片段能够按照父元素设置的适合其背景的颜色呈现自己的控件和文本。目前,无论我在父视图或
标记本身上设置了什么主题或样式,片段控件都会显示为浅背景:

我尝试将
上的
android:theme
设置为
@style/ThemeOverlay.AppCompat.Dark
@style/ThemeOverlay.AppCompat.Dark.ActionBar
,试图使文本在深色背景上呈现浅色,但运气不佳

我不希望将这种颜色切换编程到片段本身,因为我觉得主题/样式框架一定能够处理这种情况

理想情况下,我也可以在稍后阶段将一个图标与文本的颜色相匹配纳入该片段。我现在的首要任务是获得正确的文本颜色

告诉片段的一个特定实例“您在深色背景上而不是浅色背景上”或“您需要以浅色而不是深色渲染文本和控件”,并相应地进行渲染的正确方法是什么

更新 我已经在
标记上实现了一个自定义属性,并在片段的代码中对其进行初始化

以前的更新 国家:

需要注意的是,棒棒糖中的
android:theme
将分发给布局中声明的所有子级:

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

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

</LinearLayout>

我假设
容器
没有开始主题,或者充气器没有将该信息“附加”到充气的子视图。我对Android开发不够精通,无法确定哪种情况(如果有)。

通过在
标记的自定义属性中明确指定父容器的主题,并在片段初始化期间手动读取,我已经达到了预期的效果

使用
  • 确保XML的根元素具有以下
    xmlns:app
    属性:

    xmlns:app="http://schemas.android.com/apk/res-auto"
    
  • app:customTheme
    的自定义属性添加到
    标记:

    <fragment
        android:name="net.alexpeters.myapp.TaskSearchFragment"
        app:customTheme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
    
    片段
    子类
  • 添加实例变量以保存自定义主题ID:

    private @StyleRes int themeResId;
    
  • 添加一个常量以处理未传入自定义主题的情况:

    private static final int NO_CUSTOM_THEME = 0;
    
  • 按如下方式重写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();
    }
    
  • onCreateView
    方法添加一些逻辑,以将自定义主题引用注入充气机:

    @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:theme=“@style/ThemeOverlay.AppCompat.Dark”
    应用到
    时,输出是什么?在我的
    上,该属性被完全忽略,文本仍然是黑色的。在附近的一些随机的
    上,文本会像预期的那样变成白色。在屏幕截图中,第一行是一个片段,第二行是一个标准的
    EditText
    ,它们都被应用
    android:theme
    ?上面显示的两个
    EditText
    s(技术上
    AutoCompleteTextView
    s)这些是有问题的片段的实例。灯光背景上的一个没有显式应用主题,因为它已按预期渲染。在黑暗背景上的那一个明确应用了主题,但它被忽略了。你说的
    标记是什么意思?您如何管理您的片段?
    @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();
    }
    
    @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);
    }