如何在SafeArgs中从资源获取默认字符串值并正确设置Toolbar标题?
解决Safe Args默认字符串资源设置Toolbar标题的问题
我之前也碰到过这个一模一样的坑,咱们来理清楚问题根源,然后用配置的方式解决它,不用额外写代码设置Toolbar标题。
问题根源
- 当你把
app:argType="string"时,Safe Args对android:defaultValue的要求是直接的字符串字面量,不支持@string/xxx这种资源引用,所以会抛出XmlPullParserException。 - 而设
app:argType="reference"时,传递的是字符串资源的整数ID,所以Toolbar会显示一串数字,这显然不是我们想要的。
方案一:在跳转Action中设置默认参数值(推荐)
我们可以不在Fragment的Argument里设置默认值,而是把默认值放到跳转到该Fragment的Action中,这样Safe Args会正确解析资源引用为字符串:
- 修改导航图中Fragment的Argument定义,去掉
android:defaultValue:
<fragment android:id="@+id/addNewItemFragment" android:name="com.myapplication.AddNewItemFragment" android:label="Title: {title}" tools:layout="@layout/fragment_add_new_item" > <argument android:name="title" app:argType="string" /> </fragment>
- 在跳转到该Fragment的Action里添加默认参数值,引用你的字符串资源:
<fragment android:id="@+id/mainFragment" android:name="com.myapplication.MainFragment" android:label="fragment_main" tools:layout="@layout/fragment_main" > <action android:id="@+id/action_to_add_items_fragment" app:destination="@id/addNewItemFragment" > <argument android:name="title" android:defaultValue="@string/title_add_item" /> </action> </fragment>
这样配置后,当你通过这个Action跳转且不传递自定义标题时,Toolbar会自动显示Add new items;如果传递了自定义标题,就会显示你传入的内容。
方案二:使用数据绑定表达式直接在Label中处理默认值
如果你希望在Fragment的Argument里定义默认逻辑,也可以启用数据绑定后,在Label中用表达式实现“参数优先,无参数则用资源”的逻辑:
确保你的项目已经启用了数据绑定(在模块的build.gradle中设置
buildFeatures.dataBinding true)。修改导航图中Fragment的配置:
<fragment android:id="@+id/addNewItemFragment" android:name="com.myapplication.AddNewItemFragment" android:label="@{args.title != null ? args.title : @string/title_add_item}" tools:layout="@layout/fragment_add_new_item" > <argument android:name="title" app:argType="string" android:defaultValue="@null" /> </fragment>
这个表达式的意思是:如果title参数不为空,就用参数值作为标题;否则用@string/title_add_item的内容。这样也能达到你想要的效果,而且不需要修改Action的配置。
验证一下
不管用哪种方案,重新构建项目让Safe Args生成代码,然后跳转测试:
- 不传参数时,Toolbar显示
Add new items - 传递自定义标题时,显示你传入的字符串
内容的提问来源于stack exchange,提问作者AlexCarlayl
相关产品推荐
相关产品推荐

