我正在尝试根据MVVM模式设置项目,并且正在使用Jetpack的Android体系结构组件。
我有一个“ splash”片段,在该片段中发出HTTP请求,并且根据响应,用户将被导航到设置视图或主视图。
FragmentSplash:
class FragmentSplash : Fragment()
{
private lateinit var viewModelSplash: ViewModelSplash
override fun onCreateView( inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle? ): View?
{
viewModelSplash = ViewModelProviders.of( this ).get( ViewModelSplash::class.java )
return inflater.inflate(com.host.myproject.R.layout.fragment_splash, container, false )
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?)
{
viewModelSplash.command.observe(this, Observer {
when( it ) // I know strings are bad :)
{
"NAVIGATE_TO_MAIN" -> Navigation.findNavController( view ).navigate( R.id.action_showConfirm )
"NAVIGATE_TO_" -> Navigation.findNavController( view ).navigate( R.id.action_showBase )
}
});
super.onViewCreated(view, savedInstanceState)
}
}
ViewModelSplash:
class ViewModelSplash : ViewModel()
{
private val _command = MutableLiveData<String>()
val command: LiveData<String>
get() = _command
init
{
Timer("fakeHTTPRequest", false).schedule(3500) {
onInitializationFinished( response )
}
}
private fun onInitializationFinished( response : Response )
{
if( response.ok )
_command.postValue( "NAVIGATE_TO_MAIN" )
else
_command.postValue( "NAVIGATE_TO_CONFIRM" )
}
}
我看到的问题是:
-The FragmentSplash contains logic pattern the "when" statement
-The FragmentSplash is aware of other fragments
我正在尝试了解实现此目标的正确方法是什么,因为到目前为止,我所看到的所有示例都在ViewModel更改了可观察对象内的数据之后在Fragment中调用了导航器:
viewModelSplash.command.observe(this, Observer {
...
Navigation.findNavController( view ).navigate
...
我完全迷路了。.不是
与“观点/逻辑的独立性”矛盾吗?
我认为应该有某种Router类,该类从ViewModel获取通知,该类需要导航到其他地方,这样视图将完全干净。有什么建议可以从这里走吗?
答案 0 :(得分:0)
您可以尝试使导航命令在视图模型中包含实时数据,并在BaseFragment中对其进行观察。假设您要从片段A导航到片段B,然后:
sealed class NavigationCommand {
data class navigateTo(val directions: NavDirections): NavigationCommand()
object Back: NavigationCommand()
}
viewModel.navigationCommands.observe { command ->
when (command) {
is NavigationCommand.navigateTo ->
findNavController().navigate(command.directions)
NavigationCommand.Back ->
findNavController().popBackStack()
}
}
fun navigate(directions: NavDirections) {
navigationCommands.postValue(NavigationCommand.To(directions))
}
navigate(FragmentADirections.actionToFragmentB())
这只是一种方法,您可以检查此Using Navigation Architecture Component in a large banking app。 它对从视图模型导航和从片段中删除样板代码有很好的解释。