Roy*_*gel 9 android kotlin fragment-backstack android-architecture-navigation
我在执行时遇到问题
findNavController(R.id.main_nav_host).navigateUp()
Run Code Online (Sandbox Code Playgroud)
或者
findNavController(R.id.main_nav_host).popBackStack()
Run Code Online (Sandbox Code Playgroud)
它不会返回到 backstack 中的最后一个片段,而是重新打开/导航到同一/当前片段。
有人可以指出我为什么会发生这种情况的正确方向吗?
导航图:
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main_navigation_root"
app:startDestination="@+id/dest_main">
<fragment
android:id="@+id/dest_main"
android:name="com.example.popularmovies.ui.main.views.MainMoviesFragment"
android:label="@string/home"
tools:layout="@layout/fragment_main_movies">
<action
android:id="@+id/action_dest_main_to_dest_movie_details"
app:destination="@+id/dest_movie_details"
app:enterAnim="@anim/slide_in_right"
app:exitAnim="@anim/slide_out_left"
app:popEnterAnim="@anim/slide_in_left"
app:popExitAnim="@anim/slide_out_right" />
</fragment>
<fragment
android:id="@+id/dest_movie_details"
android:name="com.example.popularmovies.ui.details.movie.view.MovieDetailsFragment"
android:label="@string/movie_details"
tools:layout="@layout/fragment_movie_details"/>
</navigation>
Run Code Online (Sandbox Code Playgroud)
主活动布局:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<fragment
android:id="@+id/main_nav_host"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/main_navigation"/>
</FrameLayout>
Run Code Online (Sandbox Code Playgroud)
主要活动:
class MainActivity : AppCompatActivity(), HasSupportFragmentInjector {
@Inject
lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Fragment>
private lateinit var appBarConfiguration: AppBarConfiguration
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
initNavUi()
}
override fun onBackPressed() {
findNavController(R.id.main_nav_host).popBackStack()
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.menu_main, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
return when (item.itemId) {
R.id.action_settings -> true
else -> super.onOptionsItemSelected(item)
}
}
override fun onSupportNavigateUp(): Boolean {
return findNavController(R.id.main_nav_host).navigateUp()
}
override fun supportFragmentInjector(): AndroidInjector<Fragment> {
return dispatchingAndroidInjector
}
private fun initNavUi() {
val navController = Navigation.findNavController(this, R.id.main_nav_host)
appBarConfiguration = AppBarConfiguration(
setOf(R.id.dest_main)
)
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration)
}
}
Run Code Online (Sandbox Code Playgroud)
目的地主页片段:
class MainMoviesFragment : Fragment(), Injectable, MovieViewHolder.MovieClickListener {
@Inject
lateinit var viewModelFactory: ViewModelProvider.Factory
private lateinit var fragmentViewModel: MainMoviesFragmentViewModel
private lateinit var moviesRv: RecyclerView
private lateinit var moviesAdapter: MainMoviesAdapter
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_main_movies, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initViews(view)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
fragmentViewModel = ViewModelProviders.of(this,viewModelFactory).get(MainMoviesFragmentViewModel::class.java)
fragmentViewModel.start()
observe()
}
override fun onMovieClicked(position: Int) {
fragmentViewModel.onMovieClicked(position)
}
private fun initViews(view: View) {
moviesRv = view.findViewById<RecyclerView>(R.id.fragment_main_movies_rv).apply{
layoutManager = LinearLayoutManager(context)
setHasFixedSize(true)
moviesAdapter = MainMoviesAdapter(this@MainMoviesFragment)
adapter = moviesAdapter
}
}
private fun observe() {
fragmentViewModel.moviesLiveData.observe(this, Observer { moviesAdapter.submitList(it) })
fragmentViewModel.onMovieClickedLiveEvent.observe(this, Observer { handleMovieClickedEvent(it) })
}
private fun handleMovieClickedEvent(movieModel: MovieModel?){
val action = MainMoviesFragmentDirections.actionDestMainToDestMovieDetails()
findNavController().navigate(action)
}
}
Run Code Online (Sandbox Code Playgroud)
目标目标片段:
class MovieDetailsFragment : Fragment() {
private lateinit var viewModel: MovieDetailsFragmentViewModel
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_movie_details, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProviders.of(this).get(MovieDetailsFragmentViewModel::class.java)
}
}
Run Code Online (Sandbox Code Playgroud)
GitHub 上的项目代码可以在这里找到
您的onMovieClickedLiveEvent,在您的 中使用MainMoviesFragmentViewModel,每次返回时都会触发,MainMoviesFragment因为MutableLiveData保存了当前值。这意味着它popBackStack()工作得很好,但随后您会立即导航回详细信息页面(注意:您仍然希望删除您的代码,onBackPressed()因为现在您无法通过点击后退按钮退出应用程序)。
看起来,特别是对于变量的名称,您应该使用SingleLiveEvent 类,而不是MutableLiveData直接使用,如这篇博客文章所述。
当然,在这种情况下完全没有使用 LiveData 或通过 ViewModel 的特殊原因。您MovieViewHolder可以将MovieModel直接传递给onMovieClicked,后者可以handleMovieClickedEvent直接调用。这将避免使用 LiveData(旨在存储状态,而不是事件)并更好地模拟您实际想要实现的目标:事件侦听器。
| 归档时间: |
|
| 查看次数: |
3813 次 |
| 最近记录: |