我有一个包含产品列表片段和许多其他片段的活动,我正在尝试使用Architecture组件导航控制器。
问题是:它替换了(开始目标)产品列表片段,并且我不希望用户单击“后退”按钮时重新加载列表。
如何使片段事务作为添加而不是替换。
答案 0 :(得分:3)
您必须重写NavHostFragment的createFragmentNavigator
方法并返回YourFragmentNavigator
。
YourFragmentNavigator
必须覆盖FragmentNavigator的navigate
方法。
将FragmentNavigator的navigate
方法复制并粘贴到您的YourFragmentNavigator
中。
在导航方法中,用
更改行ft.replace(mContainerId, frag);
if (fragmentManager.fragments.size <= 0) {
ft.replace(containerId, frag)
} else {
ft.hide(fragmentManager.fragments[fragmentManager.fragments.size - 1])
ft.add(containerId, frag)
}
解决方案如下:
class YourNavHostFragment : NavHostFragment() {
override fun createFragmentNavigator(): Navigator<...> {
return YourFragmentNavigator(...)
}}
....
class YourFragmentNavigator(...) : FragmentNavigator(...) {
override fun navigate(...){
....
if (fragmentManager.fragments.size <= 0) {
ft.replace(containerId, frag)
} else {
ft.hide(fragmentManager.fragments[fragmentManager.fragments.size - 1])
ft.add(containerId, frag)
}
....
}}
在您的xml中使用YourNavHostFragment
。
答案 1 :(得分:1)
只需复制 FragmentNavigator
的代码(300 行)并将 replace()
替换为 add()
。这是目前对我来说最好的解决方案。
@Navigator.Name("fragment")
public class CustomFragmentNavigator extends
Navigator<...> {
...
public NavDestination navigate(...) {
...
ft.add(mContainerId, frag);
...
}
...
}
答案 2 :(得分:0)
稍作搜索后,这是不可能的,但是问题本身可以通过viewmodel和livedata或rxjava解决。 因此,碎片状态会在交易后保留,并且我的产品列表不会每次都重新加载
答案 3 :(得分:0)
我在等待add
和片段事务的其他选项时遇到了同样的问题,我实施了这项工作来保留回弹时的状态。
我刚刚添加了一个检查是否存在绑定,然后我恢复了先前的状态,与网络调用相同,我添加了一个检查视图模型中是否存在数据,然后不进行网络重新提取。经过测试后,它可以按预期工作。
private lateinit var binding: FragmentSearchResultsBinding
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
viewModel =
ViewModelProviders.of(this, mViewModelFactory).get(SearchResultsViewModel::class.java)
return if (::binding.isInitialized) {
binding.root
} else {
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_search_results, container, false)
with(binding) {
//some stuff
root
}
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
//reload only if search results are empty
if (viewModel.searchResults.isEmpty()) {
args.searchKey.let {
binding.toolbarHome.title = it
viewModel.onSearchResultRequest(it)
}
}
}
答案 4 :(得分:0)
@Rainmaker在我看来是正确的,我做了同样的事情。 我们还可以将回收者视图的位置/状态保存在onSaveInstanceState中 以便在导航回列表片段时返回到相同的回收者视图位置。
答案 5 :(得分:0)
Android导航组件只是替换,但您想添加片段而不是像对话框那样替换,您可以使用它,但需要最小化。 “ Version 2.1.0 ”作为导航组件。
,您会看到“ Dialog destinations ”
答案 6 :(得分:0)
我遇到了同样的问题,但就我而言,我更新了代码以使用livedata和viewmodel。 当您按回时,不会再次创建视图模型,因此您的数据得以保留。
确保您在viewmodel的init方法中进行了api调用,以便在创建viewmodel时仅发生一次