到目前为止,我只能使用导航组件成功导航到对话框并返回。问题是,我必须在对话框中做一些事情并将结果返回到调用对话框的片段。
一种方法是使用共享视图模型。但为此,我必须使用 .of(activity) ,即使我不再需要它,它也会让我的应用程序单例占用内存。
另一种方法是覆盖 show(fragmentManager, id) 方法,访问片段管理器,并从中访问前一个片段,然后可以将其设置为目标片段。我在实现回调接口之前使用过 targetFragment 方法,因此我的对话框可以将结果通知 targetFragment。但是在导航组件方法中,它感觉很笨拙,可能会在某一时刻停止工作。
还有其他方法可以做我想做的事吗?也许有办法解决第一种方法的问题?
我在一个片段里面使用childFragmentManager或在一个Activity 里面显示一个对话框supportFragmentManager,在这个过程中我想设置目标片段,如下所示:
val textSearchDialog = TextSearchDialogFragment.newInstance()
textSearchDialog.setTargetFragment(PlaceSearchFragment@this, 0)
Run Code Online (Sandbox Code Playgroud)
但是当运行该代码时,我得到错误:
java.lang.IllegalStateException:Fragment TextSearchDialogFragment {b7fce67#0 0}声明的目标片段PlaceSearchFragment {f87414#0 id = 0x7f080078}不属于此FragmentManager!
我不知道如何访问FragmentManager导航组件正在使用来管理片段的显示,有没有解决方案呢?
android kotlin android-navigation android-architecture-components android-architecture-navigation
我在我的应用程序中使用具有一个活动和两个片段的Jetpack Navigation(片段A也是家庭片段,而片段B可以从片段A导航)。
有一个intent-filter添加到MainActivity如下所示它可以接受纯文本。
<activity android:name=".MainActivity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="@string/text_mime_type_text_plain"/>
</intent-filter>
</activity>
Run Code Online (Sandbox Code Playgroud)
当用户选择从Android sharesheet我的应用程序,最终目标是通过从接收到的意图的片段B目前数据,我接收到意图在片段A(家庭片段),然后使用NavController导航到片段B使用下面的代码。
private fun checkReceivedIntent() {
val receivedUrlIntent = activity?.intent
val intentAction = receivedUrlIntent?.action
val intentType = receivedUrlIntent?.type
if (intentAction == Intent.ACTION_SEND && intentType != null) {
if (intentType == getString(R.string.text_mime_type_text_plain) ) {
val receivedText = receivedUrlIntent.getStringExtra(Intent.EXTRA_TEXT)
val action = FragmentADirections.actionFragmentAToFragmentB(receivedText)
findNavController().navigate(action)
}
}
}
Run Code Online (Sandbox Code Playgroud)
问题在于,当打开片段B时,按下工具栏的后退按钮或后退箭头(即使多次按下),也不会出现片段A,并且片段B会继续出现。
我不知道我在想什么。当用户从另一个应用程序内的共享表打开该应用程序时,这是打开特定片段的正确方法吗?
编辑
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> …Run Code Online (Sandbox Code Playgroud) android android-fragments android-jetpack android-jetpack-navigation
我已经开始使用Android体系结构组件(导航和安全Args,视图模型)以及Koin库。
目前,我在两个片段之间传递参数时遇到了问题-我需要将一个字符串值从片段A传递到片段B,在片段B中修改此值,然后将其传递回片段A。
我找到了解决我的问题的一种可能的方法-共享视图模型。不幸的是,这种方法有一个问题,因为我可以在屏幕之间传递和修改值,但是当片段A导航到另一个目标时,共享视图模型中的值仍会存储而不清除。
在Android导航中的片段之间传递和修改数据是否有其他解决方案?我想避免手动清除此值(当碎片A被破坏时)。
android android-navigation koin android-jetpack android-architecture-navigation
在片段中我setFragmentResultListener等待结果:
setFragmentResultListener(EnableFingerPrintFragment.ARG_REQUEST_KEY) { _, bundle ->
bundle.getString(EnableFingerPrintFragment.ARG_RESULT_KEY)
?.let { isActivatedResult: String ->
// DO something
}
}
findNavController().navigate(R.id.to_enableFingerPrintFragment,)
Run Code Online (Sandbox Code Playgroud)
当结果返回时,该片段将被重新创建并被onCreateView调用。
如何知道是否是onCreateView第一次创建片段被调用,还是来自返回的结果(在目标片段中设置结果之后)?
如何知道结果是否设置onViewCreated为检查此条件?
视图模型与活动或与其相连的片段一起生存和死亡。这具有一定的影响,这超出了我的范围,为什么没有人问(如果我们将Navigation体系结构引入图片中)。
根据最新的android博客和导航框架的工作方式,建议我们使用Single Activity Multiple Fragments一节。
据说我有以下应用程序设计。
Activity A (Application Entry Point)
----------
Fragment (A) (Uses ViewModel AB)
Fragment (B) (Uses ViewModel AB)
Fragment (C) (Uses ViewModel CDE)
Fragment (D) (Uses ViewModel CDE)
Fragment (E) (Uses ViewModel CDE)
Run Code Online (Sandbox Code Playgroud)
现在,由于我使用共享的视图模型,这意味着我的视图模型将附加到活动中。但是,这似乎是泄漏的。就像我从A一直遍历到E,然后又从片段弹出到片段B一样,视图模型CDE应该被销毁,但是不会被破坏,因为它已连接到活动。
同样,我们将无法将视图模型连接到片段,因为我们将共享它们的数据。
只有我提出这个问题的事实使我相信,根据我的理解,我在这里是错误的。如果我能对情况有一个适当的了解,那会很高兴。
我正在使用导航组件,我有Fragment A和Fragment B,从Fragment A我使用安全参数将一个对象发送到Fragment B并导航到它。
override fun onSelectableItemClick(position:Int,product:Product) {
val action = StoreFragmentDirections.actionNavigationStoreToOptionsSelectFragment(product,position)
findNavController().navigate(action)
}
Run Code Online (Sandbox Code Playgroud)
现在,在我的Fragment B中进行一些逻辑之后,我想再次将该数据传递给我使用的Fragment A
btn_add_to_cart.setOnClickListener {button ->
findNavController().previousBackStackEntry?.savedStateHandle?.set("optionList",Pair(result,product_position))
findNavController().popBackStack()
}
Run Code Online (Sandbox Code Playgroud)
然后在片段 A中,我用
findNavController().currentBackStackEntry?.savedStateHandle?.getLiveData<Pair<MutableList<ProductOptions>,Int>>("optionList")
?.observe(viewLifecycleOwner, Observer {
storeAdapter.updateProductOptions(it.second,it.first)
})
Run Code Online (Sandbox Code Playgroud)
现在,这工作正常,但如果我从片段 A转到片段 B并按后退按钮,上面的观察者会再次触发,复制我当前的数据,有没有办法在我只按下片段btn_add_to_cart中的按钮时触发该观察者乙?
android android-fragments kotlin android-viewmodel android-architecture-navigation
android ×7
android-architecture-navigation ×4
android-architecture-components ×2
kotlin ×2
koin ×1
navigation ×1