Nom*_*sta 24 android android-architecture-components android-jetpack android-architecture-navigation
假设我们有两个片段:MainFragment和SelectionFragment.第二个是用于选择某个对象的构建,例如整数.从第二个片段接收结果有不同的方法,如回调,总线等.
现在,如果我们决定使用导航架构组件导航到第二个片段,我们可以使用以下代码:
NavHostFragment.findNavController(this).navigate(R.id.action_selection, bundle)
Run Code Online (Sandbox Code Playgroud)
其中bundle是Bundle(当然)的实例.正如您所看到的那样,无法访问SelectionFragment我们可以进行回调的位置.问题是,如何使用Navigation Architecture Component接收结果?
小智 74
他们在 2.3.0-alpha02 版本中为此添加了一个修复程序。
如果从片段 A导航到片段 B并且A需要来自B的结果:
findNavController().currentBackStackEntry?.savedStateHandle?.getLiveData<Type>("key")?.observe(viewLifecycleOwner) {result ->
// Do something with the result.
}
Run Code Online (Sandbox Code Playgroud)
如果在Fragment B 上并且需要设置结果:
findNavController().previousBackStackEntry?.savedStateHandle?.set("key", result)
Run Code Online (Sandbox Code Playgroud)
我最终为此创建了两个扩展:
fun Fragment.getNavigationResult(key: String = "result") =
findNavController().currentBackStackEntry?.savedStateHandle?.getLiveData<String>(key)
fun Fragment.setNavigationResult(result: String, key: String = "result") {
findNavController().previousBackStackEntry?.savedStateHandle?.set(key, result)
}
Run Code Online (Sandbox Code Playgroud)
ars*_*ent 53
由于 Fragment KTX 1.3.0-alpha04 Android 支持在片段之间或片段和活动之间传递数据。这类似于startActivityForResult逻辑。
构建.gradle
implementation "androidx.fragment:fragment-ktx:1.3.0-alpha04"
Run Code Online (Sandbox Code Playgroud)
片段A.kt
class FragmentA : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
// Step 1. Listen for fragment results
setFragmentResultListener(FragmentB.REQUEST_KEY) { key, bundle ->
// read from the bundle
}
// Step 2. Navigate to Fragment B
findNavController().navigate(R.id.fragmentB)
}
}
Run Code Online (Sandbox Code Playgroud)
片段B.kt
class FragmentB : Fragment() {
companion object {
val REQUEST_KEY = "FragmentB_REQUEST_KEY"
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
buttonA.setOnClickListener { view ->
// Step 3. Set a result
setFragmentResult(REQUEST_KEY, bundleOf("data" to "button clicked"))
// Step 4. Go back to Fragment A
findNavController().navigateUp()
}
}
}
Run Code Online (Sandbox Code Playgroud)
小智 22
使用这些扩展功能
fun <T> Fragment.getNavigationResult(key: String = "result") =
findNavController().currentBackStackEntry?.savedStateHandle?.get<T>(key)
fun <T> Fragment.getNavigationResultLiveData(key: String = "result") =
findNavController().currentBackStackEntry?.savedStateHandle?.getLiveData<T>(key)
fun <T> Fragment.setNavigationResult(result: T, key: String = "result") {
findNavController().previousBackStackEntry?.savedStateHandle?.set(key, result)
}
Run Code Online (Sandbox Code Playgroud)
所以如果你想将结果从片段B发送到片段A
内部片段B
setNavigationResult(false, "someKey")
Run Code Online (Sandbox Code Playgroud)
内部片段A
val result = fragment.getNavigationResultLiveData<Boolean>("someKey")
result.observe(viewLifecycleOwner){ booleanValue-> doSomething(booleanValue)
Run Code Online (Sandbox Code Playgroud)
重要的提示
在片段 B 中,您需要将结果 (setNavigationResult()) 设置为启动或恢复状态(在 onStop() 或 onDestroy() 之前),否则 previousBackStackEntry 将已经为空。
重要说明#2
如果您只想处理一次结果,则必须在 SavedStateHandle 上调用 remove() 以清除结果。如果您不删除结果,LiveData 将继续将最后一个结果返回给任何新的 Observer 实例。
官方指南中的更多信息。
Ami*_*ifi 16
根据Google的说法:您应该尝试使用共享的ViewModel.请查看以下Google的示例:
共享ViewModel,它将包含共享数据,可以从不同的片段访问.
public class SharedViewModel extends ViewModel {
private final MutableLiveData<Item> selected = new MutableLiveData<Item>();
public void select(Item item) {
selected.setValue(item);
}
public LiveData<Item> getSelected() {
return selected;
}
}
Run Code Online (Sandbox Code Playgroud)
更新ViewModel的MasterFragment:
public class MasterFragment extends Fragment {
private SharedViewModel model;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
itemSelector.setOnClickListener(item -> {
model.select(item);
});
}
}
Run Code Online (Sandbox Code Playgroud)
DetailsFragment使用共享的ViewModel:
public class DetailFragment extends Fragment {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedViewModel model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
model.getSelected().observe(this, item -> {
// Update the UI.
});
}
}
Run Code Online (Sandbox Code Playgroud)
通过对 @LeHaine 的答案进行一点改进,您可以使用这些方法进行导航2.3.0-alpha02及以上操作
fun <T> Fragment.getNavigationResult(key: String) =
findNavController().currentBackStackEntry?.savedStateHandle?.getLiveData<T>(key)
fun <T> Fragment.setNavigationResult(result: T, key: String) {
findNavController().previousBackStackEntry?.savedStateHandle?.set(key, result)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6230 次 |
| 最近记录: |