将复杂对象作为Android导航体系结构组件中的参数传递

问题描述 投票:1回答:1

我一直在寻找Android体系结构组件的时间,最近一直在寻找导航组件的时间。

我正在尝试将一个对象作为参数传递,因此下一个片段可以检索该数据,但是要这样做,我需要执行以下两项操作之一:

  1. 将其传递给Bundle,这将使我实现对该对象的Parcelable接口。
  2. 使用我尝试过的“ Safeargs”插件,它看起来像是在后台使用了Bundles,并且仍然需要实现Parcelable接口。

关于这些选项的事情是,我读到Parcelable利用了反射功能,并且在时间上会变得非常昂贵


我还试图构建一个“ SharedMasterDetailsViewModel”,但是没有运气,因为没有在我新创建的Fragment上执行可观察到的回调。 (我认为LiveData在创建我的片段之前会执行回调)

以下是一些有关我如何尝试解决此问题的代码

SharedSessionViewModel

class SessionSharedViewModel : ViewModel() {


    var sharedSession: LiveData<Session> = MutableLiveData()
        private set

    fun setSession(data: Session) {
        val casted = this.sharedSession as MutableLiveData<Session>
        casted.postValue(data)
    }
}

MasterFragment

override fun onItemClicked(item: Session) {
    sessionSharedViewModel.setSession(item) // Item is a complex object of mine
    [email protected]().navigate(R.id.sessionDetailsFragment)
}

DetailsFragment

class SessionDetailsFragment : Fragment() {

    companion object {
        fun newInstance() = SessionDetailsFragment()
    }

    private lateinit var sharedViewModel: SessionSharedViewModel

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.session_details_fragment, container, false)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        Log.d("SESSIONDETAILS","created!")

        super.onActivityCreated(savedInstanceState)
        sharedViewModel = ViewModelProviders.of(this).get(SessionSharedViewModel::class.java)
        sharedViewModel.sharedSession.observe({this.lifecycle},{ handleUI(it!!)})
    }

    fun handleUI(sharedSession: Session) {
        Toast.makeText(activity, "This is inside new activity: ${sharedSession.title()}", Toast.LENGTH_SHORT)
    }
}

我最后的希望是将我的对象序列化为JSON字符串,并在我的Detail片段的onCreateActivity lyfecycle钩子上重新解析该对象,但是我觉得那不是正确的解决方案。

在最坏的情况下,我只是传递对象的ID并从网络中重新获取它,但是由于我已经有了想要显示的信息,因此我希望将其作为参数传递。

android kotlin navigation android-architecture-components android-livedata
1个回答
0
投票

TL; DR

您不能。

实际说明

第一件事;以下语句

关于这些选项的事情是,我读到Parcelable利用了反射功能,因此在时间上会变得非常昂贵。

是谎言

由于实现了Parcelable,您仅提供有关如何使用基本基本类型来序列化和反序列化的方法:IE:writeBytesreadBytesreadIntwriteInt

Parcelable不使用反射。 Serializable可以!

虽然的确如此,但您被迫使用Parcelable喷射大脑开发了一个非常有用的注释,它消除了必须编写称为@Parcelize的可打包实现的痛苦。

样本用法:

@Parcelize
data class User(val username: String, val password: String) : Parcelable

现在您无需编写Parcelable实现的一行就可以传递该类的实例。

更多信息here

© www.soinside.com 2019 - 2024. All rights reserved.