使用 Jetpack 传输数据
Transmit data with Jetpack
寻找一种更优雅的方式来使用 Jetpack 传输数据
现在我传递的数据如下:
override fun onListItemClick(itemIndex: Int, itemCode: String) {
val bundle = Bundle()
bundle.putString(KEY_TARGET_GUID, (adapter.getItem(itemIndex) as Target).guid)
findNavController().navigate(R.id.target_edit, bundle)
}
然后像这样在另一个片段中获取它:
private val targetGuid: String
get() = arguments?.getString(KEY_TARGET_GUID, "") ?: ""
我看到 google 的人在 codelab 中这样做了,但在他的示例中,他们创建了 class FlowStepFragmentArgs
,而且内容很多
data class FlowStepFragmentArgs(val flowStepNumber: Int = 2) : NavArgs {
fun toBundle(): Bundle {
val result = Bundle()
result.putInt("flowStepNumber", this.flowStepNumber)
return result
}
companion object {
@JvmStatic
fun fromBundle(bundle: Bundle): FlowStepFragmentArgs {
bundle.setClassLoader(FlowStepFragmentArgs::class.java.classLoader)
val __flowStepNumber : Int
if (bundle.containsKey("flowStepNumber")) {
__flowStepNumber = bundle.getInt("flowStepNumber")
} else {
__flowStepNumber = 2
}
return FlowStepFragmentArgs(__flowStepNumber)
}
}
}
问:我的情况下如何漂亮的传输数据
据我所知,使用 Jetpack Navigation 传递数据实际上只有 2 个选项。
1) 使用捆绑包。在这里我发现 budnleOf(x to y)
函数非常方便
val targetGuid = adapter.getItem(itemIndex) as Target).guid)
val bundle = bundleOf(KEY_TARGET_GUID, targetGuid)
findNavController().navigate(R.id.target_edit, bundle)
2) 通过在导航图中定义目的地参数。这将生成代码。假设你 R.id.target_edit
是一个片段:
<fragment
android:id="@+id/target_edit"
android:name="com.example.TargetEditFragment"
tools:layout="@layout/fragment_target_edit">
<argument
android:name="targetGuid"
android:defaultValue="@null"
app:argType="com.example.Target"
app:nullable="true"/>
</fragment>
然后在你的 TargetEditFragment
override fun onCreate(savedInstanceState: Bundle?) {
val targetGuid =
arguments?.let { TargetEditFragmentArgs.fromBundle(it).targetGuid }
}
使用导航架构,您可以这样做:-
让您在 navigation.xml 文件中声明片段为:-
<fragment
android:id="@+id/fragment_a"
android:name="com.example.FragmentA">
<action android:id="@+id/action_item_click"
app:destination="@id/fragment_b" />
</fragment>
<fragment
android:id="@+id/fragment_b"
android:name="com.example.fragmentB">
<argument android:name="id" app:argType="string" android:defaultValue="sample data" />
</fragment>
注:-
- 为动作发起的每个目的地创建一个 class。 这个 class 的名称是发起的名称
目的地,附加单词“Directions”。
- 此 class 具有针对在原始目标中定义的每个操作的方法。
因此对于 FragmentA class 它将生成为 FragmentADirections 例如。 -
override fun onListItemClick(itemIndex: Int, itemCode: String) {
findNavController().navigate(FragmentADirections.actionItemClick("Pass YOUR_STRING"))
}
注:-
- 为接收目的地创建了一个class。这个 class 的名称是目的地的名称,附加了单词“Args”。
并且对于 FragmentB class 它将生成,因为您可以获得数据作为 FragmentBArgs 例如:-
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// do what you want with this id
arguments?.let {bundle->
val id = FragmentBArgs.fromBundle(bundle).id
}
// OR you can do also as
// val id = arguments?.getString("id").orEmpty()
}
详情请参考https://developer.android.com/guide/navigation/navigation-pass-data
寻找一种更优雅的方式来使用 Jetpack 传输数据
现在我传递的数据如下:
override fun onListItemClick(itemIndex: Int, itemCode: String) {
val bundle = Bundle()
bundle.putString(KEY_TARGET_GUID, (adapter.getItem(itemIndex) as Target).guid)
findNavController().navigate(R.id.target_edit, bundle)
}
然后像这样在另一个片段中获取它:
private val targetGuid: String
get() = arguments?.getString(KEY_TARGET_GUID, "") ?: ""
我看到 google 的人在 codelab 中这样做了,但在他的示例中,他们创建了 class FlowStepFragmentArgs
,而且内容很多
data class FlowStepFragmentArgs(val flowStepNumber: Int = 2) : NavArgs {
fun toBundle(): Bundle {
val result = Bundle()
result.putInt("flowStepNumber", this.flowStepNumber)
return result
}
companion object {
@JvmStatic
fun fromBundle(bundle: Bundle): FlowStepFragmentArgs {
bundle.setClassLoader(FlowStepFragmentArgs::class.java.classLoader)
val __flowStepNumber : Int
if (bundle.containsKey("flowStepNumber")) {
__flowStepNumber = bundle.getInt("flowStepNumber")
} else {
__flowStepNumber = 2
}
return FlowStepFragmentArgs(__flowStepNumber)
}
}
}
问:我的情况下如何漂亮的传输数据
据我所知,使用 Jetpack Navigation 传递数据实际上只有 2 个选项。
1) 使用捆绑包。在这里我发现 budnleOf(x to y)
函数非常方便
val targetGuid = adapter.getItem(itemIndex) as Target).guid)
val bundle = bundleOf(KEY_TARGET_GUID, targetGuid)
findNavController().navigate(R.id.target_edit, bundle)
2) 通过在导航图中定义目的地参数。这将生成代码。假设你 R.id.target_edit
是一个片段:
<fragment
android:id="@+id/target_edit"
android:name="com.example.TargetEditFragment"
tools:layout="@layout/fragment_target_edit">
<argument
android:name="targetGuid"
android:defaultValue="@null"
app:argType="com.example.Target"
app:nullable="true"/>
</fragment>
然后在你的 TargetEditFragment
override fun onCreate(savedInstanceState: Bundle?) {
val targetGuid =
arguments?.let { TargetEditFragmentArgs.fromBundle(it).targetGuid }
}
使用导航架构,您可以这样做:- 让您在 navigation.xml 文件中声明片段为:-
<fragment
android:id="@+id/fragment_a"
android:name="com.example.FragmentA">
<action android:id="@+id/action_item_click"
app:destination="@id/fragment_b" />
</fragment>
<fragment
android:id="@+id/fragment_b"
android:name="com.example.fragmentB">
<argument android:name="id" app:argType="string" android:defaultValue="sample data" />
</fragment>
注:-
- 为动作发起的每个目的地创建一个 class。 这个 class 的名称是发起的名称 目的地,附加单词“Directions”。
- 此 class 具有针对在原始目标中定义的每个操作的方法。
因此对于 FragmentA class 它将生成为 FragmentADirections 例如。 -
override fun onListItemClick(itemIndex: Int, itemCode: String) {
findNavController().navigate(FragmentADirections.actionItemClick("Pass YOUR_STRING"))
}
注:-
- 为接收目的地创建了一个class。这个 class 的名称是目的地的名称,附加了单词“Args”。
并且对于 FragmentB class 它将生成,因为您可以获得数据作为 FragmentBArgs 例如:-
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// do what you want with this id
arguments?.let {bundle->
val id = FragmentBArgs.fromBundle(bundle).id
}
// OR you can do also as
// val id = arguments?.getString("id").orEmpty()
}
详情请参考https://developer.android.com/guide/navigation/navigation-pass-data