gpt4 book ai didi

Android 导航组件 - 向上导航打开相同的 fragment

转载 作者:搜寻专家 更新时间:2023-11-01 09:20:57 25 4
gpt4 key购买 nike

我在执行时遇到问题

findNavController(R.id.main_nav_host).navigateUp()

findNavController(R.id.main_nav_host).popBackStack()

它不会返回到后台堆栈中的最后一个 fragment ,而是重新打开/导航到相同/当前 fragment 。

有人能为我指出正确的方向吗?

导航图:

<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>

MainActivity 布局:

<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>

主要 Activity :

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)
}

}

目标主页 fragment :

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)
}

}

目标目标 fragment :

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)
}

}

GitHub上的项目代码可以查到here

最佳答案

你的 onMovieClickedLiveEvent , 用于你的 MainMoviesFragmentViewModel , 每次你回到你的 MainMoviesFragment 时都会开火自 MutableLiveData保存当前值。这意味着 popBackStack()工作正常,但随后您会立即导航回到详细信息页面(注意:您仍然希望删除 onBackPressed() 中的代码,因为现在您无法通过点击后退按钮退出应用程序)。

看起来,尤其是对于变量名,您应该使用 SingleLiveEvent class , 而不是 MutableLiveData直接,根据this blog post .

当然,在这种情况下,没有特别的理由使用 LiveData 或通过 ViewModel。你的MovieViewHolder可以通过 MovieModel直接到onMovieClicked , 可以调用 handleMovieClickedEvent直接地。这将避免使用 LiveData(旨在存储状态,而不是事件)并更好地模拟您实际想要实现的目标:事件监听器。

关于Android 导航组件 - 向上导航打开相同的 fragment ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55539486/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com