android-fragments 如何使用导航参数移动到下一个片段?

9fkzdhlc  于 2022-11-13  发布在  Android
关注(0)|答案(1)|浏览(193)

这是我的应用程序的主要活动。我正在使用导航控制器。

class MainActivity : AppCompatActivity() {

    lateinit var viewModel: NewsViewModel
    lateinit var navController: NavController
    override fun onCreate(savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val newRepository = NewsRepository(ArticleDatabase(this))
        val viewModelProviderFactory = NewsViewModelProviderFactory(newRepository)
        viewModel = ViewModelProvider(this , viewModelProviderFactory).get(NewsViewModel::class.java)
//        bottomNavigationView.setupWithNavController(newsNavHostFragment.findNavController())

        val navHostFragment= supportFragmentManager.findFragmentById(R.id.newsNavHostFragment) as NavHostFragment
        navController= navHostFragment.navController
        bottomNavigationView.setupWithNavController(navController)
    }

这是突发新闻片段,其他片段的功能都一样,所以只发布这一条

class BreakingNewsFragment : Fragment (R.layout.fragment_breaking_news) {

    lateinit var viewModel: NewsViewModel
    lateinit var newsAdapter: NewsAdapter

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        viewModel = (activity as MainActivity).viewModel
        setUpRecyclerView()

        newsAdapter!!.setOnItemClickListener {
            val bundle = Bundle().apply {
                putSerializable("article" , it)
            }
            findNavController().navigate(
                R.id.action_breakingNewsFragment_to_articleFragment2 , bundle
            )
        }
        viewModel.breakingNews.observe(viewLifecycleOwner, Observer { response ->
            when(response) {
                is Resource.Success -> {
                    hideProgressBar()
                    response.data?.let { newsResponse ->
                        newsAdapter.differ.submitList(newsResponse.articles)
                    }
                }
                is Resource.Error -> {
                    hideProgressBar()
                    response.message?.let { message ->
                        Log.e("Breaking Fragment", "An error occured: $message")
                    }
                }
                is Resource.Loading -> {
                    showProgressBar()
                }
            }
        })
    }

    private fun hideProgressBar() {
        paginationProgressBar.visibility = View.INVISIBLE
    }

    private fun showProgressBar() {
        paginationProgressBar.visibility = View.VISIBLE
    }

     fun setUpRecyclerView() {

         newsAdapter = NewsAdapter()
         rvBreakingNews.apply {
             adapter = newsAdapter
             layoutManager = LinearLayoutManager(activity)
         }
    }
}

这是从Yoututub菲利普拉克纳的教程。这里的链接原来的项目
https://github.com/philipplackner/MVVMNewsApp。他的片段版本是不赞成的,所以我在xml文件中使用了新的片段视图。所以在使用导航控制器时有一个问题。
编辑-〉忘记输入错误。在这里

2022-10-17 01:08:09.796 3971-3971/com.arpit.newsapp20 E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.arpit.newsapp20, PID: 3971
    java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.hashCode()' on a null object reference
        at com.arpit.newsapp20.models.Article.hashCode(Unknown Source:15)
        at androidx.navigation.NavBackStackEntry.hashCode(NavBackStackEntry.kt:256)
        at java.util.HashMap.hash(HashMap.java:338)
        at java.util.HashMap.put(HashMap.java:611)
        at androidx.navigation.NavController.linkChildToParent(NavController.kt:143)
        at androidx.navigation.NavController.addEntryToBackStack(NavController.kt:1918)
        at androidx.navigation.NavController.addEntryToBackStack$default(NavController.kt:1813)
        at androidx.navigation.NavController$navigate$4.invoke(NavController.kt:1721)
        at androidx.navigation.NavController$navigate$4.invoke(NavController.kt:1719)
        at androidx.navigation.NavController$NavControllerNavigatorState.push(NavController.kt:287)
        at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.kt:198)
        at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.kt:164)
        at androidx.navigation.NavController.navigateInternal(NavController.kt:260)
        at androidx.navigation.NavController.navigate(NavController.kt:1719)
        at androidx.navigation.NavController.navigate(NavController.kt:1545)
        at androidx.navigation.NavController.navigate(NavController.kt:1472)
        at androidx.navigation.NavController.navigate(NavController.kt:1454)
        at com.arpit.newsapp20.ui.BreakingNewsFragment$onViewCreated$1.invoke(BreakingNewsFragment.kt:31)
        at com.arpit.newsapp20.ui.BreakingNewsFragment$onViewCreated$1.invoke(BreakingNewsFragment.kt:27)
        at com.arpit.newsapp20.adapters.NewsAdapter.onBindViewHolder$lambda-2$lambda-1(NewsAdapter.kt:56)
        at com.arpit.newsapp20.adapters.NewsAdapter.$r8$lambda$FmTlKYZBcoLQp02jU2NS9dL1z-k(Unknown Source:0)
        at com.arpit.newsapp20.adapters.NewsAdapter$$ExternalSyntheticLambda0.onClick(Unknown Source:4)
        at android.view.View.performClick(View.java:7441)
        at android.view.View.performClickInternal(View.java:7418)
        at android.view.View.access$3700(View.java:835)
        at android.view.View$PerformClick.run(View.java:28676)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loopOnce(Looper.java:201)
        at android.os.Looper.loop(Looper.java:288)
        at android.app.ActivityThread.main(ActivityThread.java:7839)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)

这里是文章类

@Entity(
    tableName = "articles"
)
data class Article(
    @PrimaryKey(autoGenerate = true)
    var id: Int? = null,
    val author: String,
    val content: String?,
    val description: String,
    val publishedAt: String,
    val source: Source,
    val title: String,
    val url: String,
    val urlToImage: String
) : Serializable

下面是news适配器类

class NewsAdapter  : RecyclerView.Adapter<NewsAdapter.ArticleViewHolder>() {

    inner class ArticleViewHolder(itemView: View): RecyclerView.ViewHolder(itemView)

    private val differCallback = object : DiffUtil.ItemCallback<Article>() {
        override fun areItemsTheSame(oldItem: Article, newItem: Article): Boolean {
            return oldItem.url == newItem.url
        }

        override fun areContentsTheSame(oldItem: Article, newItem: Article): Boolean {
            return oldItem == newItem
        }
    }

    val differ = AsyncListDiffer(this, differCallback)

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ArticleViewHolder {
        return ArticleViewHolder(
            LayoutInflater.from(parent.context).inflate(
                R.layout.item_article_preview,
                parent,
                false
            )
        )
    }

    override fun getItemCount(): Int {
        return differ.currentList.size
    }

    private var onItemClickListener: ((Article) -> Unit)? = null

    override fun onBindViewHolder(holder: ArticleViewHolder, position: Int) {
        val article = differ.currentList[position]
        holder.itemView.apply {
            Glide.with(this).load(article.urlToImage).into(ivArticleImage)
            tvSource.text = article.source.name
            tvTitle.text = article.title
            tvDescription.text = article.description
            tvPublishedAt.text = article.publishedAt

            setOnClickListener {
                onItemClickListener?.let { it(article) }
            }
        }
    }

    fun setOnItemClickListener(listener: (Article) -> Unit) {
        onItemClickListener = listener
    }
}
a9wyjsp7

a9wyjsp71#

你看起来想把点击的新闻条目传递给文章片段。但是在你的点击监听器中,你并没有接收到点击的条目。相反,你在“it”中传递了一些其他的东西。我想这就是为什么你会得到一个空指针异常的原因。你需要像下面这样的东西:

newsAdapter!!.setOnItemClickListener {
            val newsItem = // get clicked news item from adapter
                newsItem?.let {
                    val bundle = Bundle().apply {
                        putSerializable("article" , it)
                    }
                    findNavController().navigate(
                        R.id.action_breakingNewsFragment_to_articleFragment2 , bundle
                    )
                }
        }

相关问题