为什么Android主题不会影响片段内的元素?

时间:2015-11-15 21:45:15

标签: android android-fragments android-theme

我有一个托管FrameLayout的活动,并动态显示自定义片段。

我的目标是在styles.xml中定义适用于所有片段内所有按钮的按钮样式。

这是我的 styles.xml 文件:

<!-- Base application theme. -->
<style name="AppThemeDark" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:buttonStyle">@style/bt</item>
</style>

<style name="bt" parent="@android:style/Widget.Button">
    <item name="android:background">#992323</item>
</style>

activity_login.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context="com.example.app.LoginActivity">


    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/login_frame_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"/>

</LinearLayout>

最后是 fragment.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        android:paddingBottom="@dimen/activity_vertical_margin"
        tools:context="com.example.app.LoginBackupKeyFragment"
        android:orientation="vertical">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Got it!"
        android:id="@+id/button"
        android:layout_gravity="center_horizontal"
        android:onClick="BackupKeyGotItButtonClicked"/>


</LinearLayout>

但样式不适用!为什么呢?

编辑15.11.2015

在阅读完这个问题之后,我想我应该提一下,我在我的片段中使用自定义onCreateView函数,它看起来像这样:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    // create ContextThemeWrapper from the original Activity Context with the custom theme
    final Context contextThemeWrapper = new ContextThemeWrapper(getActivity(), R.style.AppThemeDark);

    // clone the inflater using the ContextThemeWrapper
    LayoutInflater localInflater = inflater.cloneInContext(contextThemeWrapper);

    View fragmentView = localInflater.inflate(R.layout.fragment_login_new, container, false);

    pass1 = (EditText)fragmentView.findViewById(R.id.login_new_pass1);

    return fragmentView;
}

编辑2 15.11.2015 这是我的清单XML

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.app" >

    <uses-permission android:name="android.permission.READ_SMS" />

    <application>

        <activity android:name=".StartUpActivity"
            android:theme="@style/AppTheme.NoActionBar"
            android:noHistory="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />

                <action android:name="android.intent.action.DEFAULT" />
            </intent-filter>
        </activity>


        <activity
            android:name=".LoginActivity"
            android:label="@string/title_activity_login"
            android:theme="@style/AppThemeDark"
            android:windowSoftInputMode="adjustResize">
        </activity>
    </application>

</manifest>

编辑3 !!重要!!

我注意到这必须与

有关
<item name="android:buttonStyle">@style/bt</item>

例如添加此

<item name="colorControlNormal">#f00</item>
<item name="colorControlActivated">#0f0</item>
<item name="colorControlHighlight">#00f</item>

进入AppThemeDark样式并在片段中显示确定。只是android:buttonStyle和simmilaruly,例如android.editTextStyle不起作用。

2 个答案:

答案 0 :(得分:0)

可能为时已晚,但如果我理解正确,您希望在主题中设置全局指定的colorControlNormalcolorControlActivatedcolorControlHighlight,并将其仅应用于按钮。我有类似的问题(我想要EditText的白色强调色)并且我已经解决了它如下:

  1. values/styles中创建样式:

    <style name="ColorOverwrite" parent="AppTheme"> <item name="android:textColorHint">@color/white_54p</item> <item name="colorAccent">@color/colorWhite</item> <item name="colorControlNormal">@color/white_54p</item> <item name="colorControlActivated">@color/colorWhite</item> </style>

  2. 添加app:theme="@style/ColorOverwrite"更新 app:theme="..."现已弃用,我们应该使用android:theme="")进行特定控制(在我的情况下为EditText)

    <EditText android:id="@+id/id" android:textColor="@color/colorBlueLight" android:inputType="text" app:theme="@style/ColorOverwrite" android:layout_width="match_parent" android:layout_height="wrap_content" />

  3. 确保您同时为该控件设置style="@style/somestyle",否则您将收到错误。
  4. 红色矩形中的

    Example image showing applied theme - EditText具有我的自定义主题,黄色矩形中的EditText显示来自主题的默认颜色样式

答案 1 :(得分:0)

您可以在 Fragment 中覆盖 onGetLayoutInflater


    /*Set Light theme for the fragment;It overrides activity theme and set Light*/
    override fun onGetLayoutInflater(bundle: Bundle?): LayoutInflater {
        val contextThemeWrapper = ContextThemeWrapper(activity, R.style.AppTheme_Light)

        // clone the inflater using the ContextThemeWrapper
        val inflater = super.onGetLayoutInflater(bundle)
        return inflater.cloneInContext(contextThemeWrapper)
    }

此外,如果您想从覆盖主题中获取颜色属性,请在片段中执行此操作:

val colorInt = MaterialColors.getColor(getLayoutInflater().context, R.attr.colorAccent, Color.WHITE)