【问题标题】:Why Android theme does not affect elements inside of fragment?为什么Android主题不会影响片段内的元素?
【发布时间】:2015-11-15 21:45:15
【问题描述】:

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

我的目标是在 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 和类似的,例如android.editTextStyle 不起作用。

【问题讨论】:

  • 请发布您的 manifest.xml 代码
  • 我已经发布了清单

标签: android android-fragments android-theme


【解决方案1】:

可能为时已晚,但如果我理解正确,您想设置不同的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"UPDATE 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",否则会出错。

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

【讨论】:

    【解决方案2】:

    您可以在 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)
    

    【讨论】:

      猜你喜欢
      • 2021-01-23
      • 2014-11-25
      • 2017-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-01
      相关资源
      最近更新 更多