I found the question but does not have solution in code
当要进行后退/手动后退时,我想获取数据。我正在使用navigateUp()
返回。如何将数据传递到上一个片段? navigateUp()
没有任何工具可以将数据传递到上一个片段。甚至我都没有找到使用Safe Args的解决方案。它正在转发数据。我想在向后Frad B-> Frag A中找到
我的代码返回上一个片段
Navigation.findNavController(view).navigateUp()
我的问题是,如何获取上一个片段中的数据。我可以使用
从Frag B导航到Frag A答案 0 :(得分:2)
根据developer.android.com,对于要使用其活动范围共享数据ViewModel的片段,可以使用common。
以下是步骤:
class SharedViewModel : ViewModel() {
val dataToShare = MutableLiveData<String>()
fun updateData(data: String) {
dataToShare.value = data
}
}
class Fragment1 : Fragment() {
private lateinit var viewModel: SharedViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = ViewModelProviders.of(activity!!).get(SharedViewModel::class.java)
model.dataToShare.observe(this, Observer<String> { dataFromFragment2 ->
// do something with data
})
}
}
Fragment2
中的数据,现在,如果您正确处理了导航,则应该可以在Fragment1
上接收数据更改:class Fragment2 : Fragment() {
private lateinit var viewModel: SharedViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = ViewModelProviders.of(activity!!).get(SharedViewModel::class.java)
updateDataButton.setOnClickListener { v ->
viewModel.updateData("New data for fragment1")
}
}
}
我希望答案会有所帮助。
答案 1 :(得分:1)
您应该使用静态变量/伴侣对象,因为它不是简单/精巧的体系结构,因此比共享视图模型更好。由于它并不简单,我认为这是最好的方法。
要从FragmentB导航到FragmentA
FragmentB:
MyOptional is <undefined>
MyOptional is abc
FragmentA:
isBackpressed = true
findNavController().navigateUp()
答案 2 :(得分:0)
您可以NavigationResult库。基本上是startActivityForResult
,但用于导航组件中的片段。
答案 3 :(得分:0)
您可以致电
findNavController().navigate(R.id.fragment1, args)
其中args是您的软件包。 在fragment1中,从参数中获取数据
答案 4 :(得分:0)
要在从一个目的地导航到另一个目的地时弹出目的地,请向关联的app:popUpTo
元素添加<action>
属性。
要使用参数从fargment2导航到Fragment1,请在导航图中指定呼叫者片段的action
和目标片段的arguments
:
<fragment
android:id="@+id/fragment2"
android:name="com.example.myapplication.Fragment2"
android:label="fragment_2"
tools:layout="@layout/fragment_2">
<action
android:id="@+id/action_2_to_1"
app:destination="@id/fragment1"
app:popUpTo="@+id/fragment1"/>
</fragment>
<fragment
android:id="@+id/fragment1"
android:name="com.example.myapplication.Fragment1"
android:label="fragment_1"
tools:layout="@layout/fragment_1">
<argument
android:name="someArgument"
app:argType="string"
app:nullable="false"
android:defaultValue="Hello Word"/>
</fragment>
在Fragment2类中,您调用操作并传递参数:
val action = Fragment2Directions.action2To1("MY_STRING_ARGUMENT")
findNavController().navigate(action)
答案 5 :(得分:0)
请使用官方androidx的组件。 setFragmentResultListener() 和 setFragmentResult() 方法:
implementation "androidx.fragment:fragment-ktx:1.3.3"
干杯;)
答案 6 :(得分:-1)
您可以使用以下简单实现在 popBackStack()之后通过 Android导航组件传递数据。此方法基于官方Google documentation
您只需要使用BaseFragment扩展您的片段并使用以下方法:
//to start Fragment2 for result
startFragmentForResult(actionId: Int)
//to perform pop back stack in Fragment2
popBackStackWithResult(result: Any)
//to observe your result in Fragment1
onFragmentResult(result: Any)
添加SharedViewModel类
class SharedViewModel : ViewModel() {
val sharedData = MutableLiveData<Any>()
fun share(obj: Any) {
sharedData.value = obj
}
}
添加BaseFragment类
import androidx.fragment.app.Fragment
abstract class BaseFragment : Fragment() {
protected var rootView: View? = null
private var sharedViewModel: SharedViewModel? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
if (rootView == null) {
rootView = inflater.inflate(getLayoutId(), container, false)
initSharedViewModel()
}
return rootView
}
abstract fun getLayoutId()
open fun onFragmentResult(result: Any){
//TODO implement in descendants
}
protected fun startFragmentForResult(actionId: Int){
findNavController().navigate(actionId)
}
protected fun popBackStackWithResult(result: Any){
findNavController().popBackStack()
sharedViewModel?.share(result)
}
private fun initSharedViewModel() {
sharedViewModel = ViewModelProvider(activity!!).get(SharedViewModel::class.java)
sharedViewModel?.sharedData?.observe(activity!!, object : Observer<Any> {
override fun onChanged(params: Any) {
onFragmentResult(params)
}
})
}
}
添加Fragment1
class Fragment1 : BaseFragment(){
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
some_btn.setOnClickListener{
startFragmentForResult(R.id.action_fragment1_to_fragment2)
}
}
override fun onFragmentResult(result: Any) {
if(result is AnyYourClass){
//PERFECT! DO SOMETHING WITH YOUR RESULT
}
}
}
添加Fragment2
class Fragment2 : BaseFragment(){
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
some_btn.setOnClickListener{
popBackStackWithResult(AnyYourClass())
}
}
}
干杯;)