CollapsingToolbarLayout展开时标题忽略textStyle与fontStyle问题排查
你遇到的这个问题,核心原因是CollapsingToolbarLayout的app:toolbarId属性在起作用。当你给CollapsingToolbarLayout设置了app:toolbarId="@+id/toolbar"时,这个Toolbar会被认定为CollapsingToolbarLayout关联的"主工具栏",此时折叠状态下的标题绘制权会被CollapsingToolbarLayout接管,而不是由Toolbar自己处理。
虽然你给Toolbar本身设置了app:titleTextAppearance="@style/ToolbarTextAppearance",但当CollapsingToolbarLayout接管标题后,它会优先使用自身的collapsedTitleTextAppearance属性来控制标题样式——哪怕你已经把这个属性也设置成了ToolbarTextAppearance,这里还有个细节:CollapsingToolbarLayout的标题样式属性和Toolbar的标题样式属性,对某些样式项的解析规则不一样。
具体来说,你定义的ToolbarTextAppearance里用了android:textStyle和android:fontFamily这些带android:前缀的属性,但CollapsingToolbarLayout在处理折叠标题样式时,对于textStyle和fontFamily,需要使用不带android:前缀的属性名(也就是textStyle和fontFamily)才能生效。而你的toolbar2因为没有被设为关联工具栏,标题完全由自己处理,所以带android:前缀的属性都能正常识别。
针对你的需求,有两种靠谱的解决方式,你可以根据自己的场景选择:
方案一:移除CollapsingToolbarLayout的app:toolbarId属性
如果你不需要CollapsingToolbarLayout接管这个Toolbar的标题逻辑,直接删掉CollapsingToolbarLayout标签里的app:toolbarId="@+id/toolbar"。这样两个Toolbar都会完全使用自己设置的app:titleTextAppearance="@style/ToolbarTextAppearance",样式就能统一了。
修改后的CollapsingToolbarLayout代码片段:
<android.support.design.widget.CollapsingToolbarLayout android:id="@+id/toolbar_layout" android:layout_width="match_parent" android:layout_height="match_parent" app:contentScrim="?attr/colorPrimary" app:layout_scrollFlags="scroll|exitUntilCollapsed" app:expandedTitleTextAppearance="@style/ToolbarTextAppearance" app:expandedTitleMarginBottom="20dp" app:expandedTitleMarginStart="18dp" app:collapsedTitleTextAppearance="@style/ToolbarTextAppearance">
方案二:修改样式属性,适配CollapsingToolbarLayout的规则
如果你需要保留app:toolbarId的设置(比如要利用CollapsingToolbarLayout的一些ActionBar联动特性),那你需要调整ToolbarTextAppearance的定义,给textStyle和fontFamily同时添加带android:和不带前缀的版本,确保不管是Toolbar自己解析还是CollapsingToolbarLayout解析,都能识别到这些属性:
<style name="ToolbarTextAppearance"> <item name="android:textSize">22sp</item> <!-- 同时添加带前缀和不带前缀的属性 --> <item name="android:textStyle">bold</item> <item name="textStyle">bold</item> <item name="android:textColor">@color/colorWhite</item> <item name="android:fontFamily">sans-serif</item> <item name="fontFamily">sans-serif</item> </style>
这样修改后,CollapsingToolbarLayout接管折叠标题时,会读取不带前缀的textStyle和fontFamily,而Toolbar自己处理标题时会读取带前缀的,两边的样式就能统一了。
另外还有个小建议:如果你的minSdkVersion允许,尽量迁移到AndroidX的组件(比如com.google.android.material.appbar.CollapsingToolbarLayout),新版的Material组件在样式兼容性上会更好,类似的小坑会少很多。
内容的提问来源于stack exchange,提问作者ivan8m8

