Android中TextInputLayout结合Calligraphy3库崩溃的解决方法
从你的Logcat报错里一眼就能抓到核心问题:
Caused by: java.lang.IllegalArgumentException: The style on this component requires your app theme to be Theme.MaterialComponents (or a descendant).
简单来说,你用的TextInputLayout是Material Design组件库的控件,它强制要求App的主题必须继承自Theme.MaterialComponents系列,而你的当前主题应该还是传统的AppCompat主题,直接导致控件初始化失败。结合你在用Calligraphy3设置自定义字体的场景,我给你分步解决:
1. 把App主题切换为MaterialComponents主题
打开res/values/styles.xml(如果有夜间模式,别忘了同步修改values-night/styles.xml),把你的基础主题的parent换成MaterialComponents的主题,比如常用的无ActionBar版本:
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar"> <!-- 保留你原有的主题配置,比如颜色、状态栏设置 --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> <!-- 加上Calligraphy3需要的字体配置属性,对应你assets里的字体路径 --> <item name="fontPath">fonts/your_custom_font.ttf</item> </style>
不用担心Material主题会破坏原有布局,它完全兼容AppCompat的所有属性,只是扩展了Material组件的支持。
2. 确认Calligraphy3的Application配置正确
Calligraphy3需要通过自定义Application来初始化ViewPump,确保你的代码是这样的(如果还没写就补上):
public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); // 初始化ViewPump和Calligraphy拦截器 ViewPump.init(ViewPump.builder() .addInterceptor(new CalligraphyInterceptor( new CalligraphyConfig.Builder() .setDefaultFontPath("fonts/your_custom_font.ttf") .setFontAttrId(R.attr.fontPath) .build())) .build()); } @Override protected void attachBaseContext(Context base) { super.attachBaseContext(ViewPumpContextWrapper.wrap(base)); } }
注意setDefaultFontPath里的路径要和你放在assets/fonts/下的字体文件完全对应,主题里的fontPath属性也要和这个一致。
3. 检查TextInputLayout的样式(可选)
你的XML里已经用了@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox,这个是Material组件的原生样式,在Material主题下可以直接正常工作,不需要修改。如果之后你想自定义TextInputLayout的样式,记得让自定义样式的parent也继承MaterialComponents的样式,比如:
<style name="MyCustomTextInputLayout" parent="Widget.MaterialComponents.TextInputLayout.OutlinedBox"> <!-- 自定义你的样式属性,比如边框颜色、宽度等 --> <item name="boxStrokeColor">@color/colorAccent</item> <item name="boxStrokeWidth">@dimen/_1sdp</item> </style>
额外提醒
- 如果某些Activity单独设置了主题,要确保这些主题也继承自
Theme.MaterialComponents,不然只要页面里用了Material组件还是会崩溃。 - 如果你担心依赖版本兼容,可以把Material Components库的依赖更新到最新稳定版(和Calligraphy3 3.1.1完全兼容)。
内容的提问来源于stack exchange,提问作者Dr Circle

