首页 > 解决方案 > 向上导航无法返回首页 Fragment

问题描述

我的应用程序上有 3 个片段(HomeFragment、NewsFragment、DetailFragment),后退按钮按原样工作。向上导航的工作方式与系统后退按钮类似,但是当单击 NewsFragment 时,向上导航无法将我带回 HomeFragment,而后退按钮可以。

这是我的代码:

MainActivity.kt

    package com.example.google_like

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.navigation.findNavController
import androidx.navigation.ui.NavigationUI
import com.example.google_like.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {
    lateinit var binding: ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this,R.layout.activity_main)
        val navController = this.findNavController(R.id.nav_host_fragment)
        NavigationUI.setupActionBarWithNavController(this, navController)

    }

    override fun onSupportNavigateUp(): Boolean {
        val navController = this.findNavController(R.id.nav_host_fragment)
        return navController.navigateUp()
    }





}

HomeFragment.kt:

    package com.example.google_like.home

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import com.example.google_like.databinding.FragmentHomeBinding


class HomeFragment : Fragment() {
lateinit var binding: FragmentHomeBinding
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment

        binding= FragmentHomeBinding.inflate(inflater)
        binding.lifecycleOwner = this

        binding.button.setOnClickListener {

            this.findNavController().navigate(HomeFragmentDirections.actionHomeFragmentToNewsFragment())

        }

        return binding.root
    }


}

新闻片段.kt:

package com.example.google_like.news

import android.os.Bundle
import android.util.Log
import android.view.*
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import com.example.google_like.R
import com.example.google_like.databinding.FragmentNewsBinding
const val LOG_TAG = "NewsFragment"

class NewsFragment : Fragment() {

    private val newsViewModel : NewsViewModel by lazy {
    ViewModelProvider(this).get(NewsViewModel::class.java)
}
    lateinit var binding: FragmentNewsBinding
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        Log.i(LOG_TAG,"onCreateView() called")
        binding = FragmentNewsBinding.inflate(inflater)
        Log.i(LOG_TAG,"binding")

        binding.lifecycleOwner = this

        binding.recycleView.adapter = NewsAdapter(NewsAdapter.OnClickListener{
        this.findNavController().navigate(NewsFragmentDirections.actionNewsFragmentToDetailFragment(it))
        })
        Log.i(LOG_TAG,"recyclerView adapter")


        binding.viewModel = newsViewModel
        Log.i(LOG_TAG,"binding.viewModel = newsViewModel")
        setHasOptionsMenu(true)
        return binding.root
    }

    override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
        super.onCreateOptionsMenu(menu, inflater)
        inflater.inflate(R.menu.overflow_menu,menu)
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {

        newsViewModel.updateFilter(when(item.itemId){
            R.id.show_buy_menu -> MarsApiFilter.SHOW_BUY
            R.id.show_rent_menu -> MarsApiFilter.SHOW_RENT
            else -> MarsApiFilter.SHOW_ALL
        })
        return true
    }
}

细节片段.kt

class DetailFragment : Fragment() {
    lateinit var binding: FragmentDetailBinding
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
       binding = FragmentDetailBinding.inflate(inflater)
        binding.lifecycleOwner = this
        val arguments = DetailFragmentArgs.fromBundle(requireArguments()).property
        val application = requireActivity().application

        val detailViewModelFactory = DetailViewModelFactory(arguments,application)
        val detailViewModel = ViewModelProvider(this,detailViewModelFactory).get(DetailViewModel::class.java)
        binding.viewModel = detailViewModel

        return binding.root
    }
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.google_like">
<uses-permission android:name="android.permission.INTERNET"/>
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity android:name=".MainActivity"
            android:parentActivityName=".MainActivity">

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

BindingAdapter.kt(RecyclerView 位于 NewsFragment 上。当单击向上导航但 onCreateView() 没有时,也会调用此绑定适配器。通常,应在 LiveData<List>(作为参数传递)更改时调用此绑定适配器。我知道为什么会这样?)

@BindingAdapter("listData")
fun RecyclerView.bindData(list: List<MarsProperty>?){
    Log.i("BindingAdapter","bindData() called")

        val adapter = this.adapter as NewsAdapter
        adapter.submitList(list)


}

标签: androidkotlinandroid-fragmentsandroid-navigationkotlin-android-extensions

解决方案


推荐阅读