【问题标题】:How to use data from onActivityResult in MVVM architecture?如何在 MVVM 架构中使用来自 onActivityResult 的数据?
【发布时间】:2020-04-25 04:09:51
【问题描述】:

如何在 MVVM 架构中使用来自 onActivityResult 的数据?我需要向订阅的 RecyclerView 添加一个项目以从 ViewModel 接收数据。如何将数据从 onActivityResult 发送到 ViewModel 类,然后更新我的列表?如果我立即从 onactivityresult 方法向适配器添加数据,则不会发生任何事情。在这个问题上我需要任何帮助

活动类:

class ContactsActivity : AppCompatActivity(), ContactsListener {
    private val TAG = "ContactsActivity"

    @Inject
    lateinit var factory: ViewModelProvider.Factory
    lateinit var contactsViewModel: ContactsViewModel


    companion object {
        const val ADD_CONTACT_REQUEST = 200
    }

    private lateinit var mAdapter: ContactsAdapter

    @SuppressLint("WrongConstant")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        toolbar_contacts.title = getString(R.string.contacts_toolbar_title)

        add_new_contact_btn.setOnClickListener {
            val intent = Intent(this@ContactsActivity, AddContactActivity::class.java)
            startActivityForResult(intent, ADD_CONTACT_REQUEST)
        }

        DaggerContactsActivity_ContactsComponent.create().inject(this@ContactsActivity)
        contactsViewModel = ViewModelProviders.of(this@ContactsActivity, factory).get(ContactsViewModel::class.java)
        contactsViewModel.getContactsList().observe(this@ContactsActivity, Observer {

            mAdapter = ContactsAdapter(this@ContactsActivity, it)
            recycler_contacts.layoutManager =
                LinearLayoutManager(applicationContext, OrientationHelper.VERTICAL, false)
            recycler_contacts.adapter = mAdapter
            recycler_contacts.setHasFixedSize(true)

            mAdapter.sortByName()

        })
    }

    // Dagger create
    @Component (modules = [ContactsModule::class])
    interface ContactsComponent {

        fun inject (activity: ContactsActivity)
    }

    @Module
    abstract class ContactsModule {

        @Binds
    abstract fun bindViewModelFactory(factory: ContactsViewModelFactory): ViewModelProvider.Factory
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
            if (resultCode == ADD_CONTACT_REQUEST && resultCode == RESULT_OK) {
                val firstName: String? = data?.getStringExtra(AddContactActivity.EXTRA_FIRST_NAME)
                val lastName: String? = data?.getStringExtra(AddContactActivity.EXTRA_LAST_NAME)
                val phone: String? = data?.getStringExtra(AddContactActivity.EXTRA_PHONE)
                val email: String? = data?.getStringExtra(AddContactActivity.EXTRA_EMAIL)
                val notes: String? = data?.getStringExtra(AddContactActivity.EXTRA_NOTES)

                val contacts = Contacts(firstName = firstName.toString(), lastName = lastName.toString(), phone = phone.toString(),
                    email = email.toString(), notes = notes.toString(), images = "")

                contactsViewModel.get(contacts = contacts)
            }
        }

    override fun setupContactsList(contactsList: ArrayList<Contacts>) {

        mAdapter.setupContacts(contactsList = contactsList)
    }
}

【问题讨论】:

  • 我认为根本不需要startActivityForResultonActivityResult。第二个活动可以修改实时数据,第一个活动可以观察它的变化。
  • 我该如何实现这个?

标签: android kotlin mvvm android-recyclerview android-mvvm


【解决方案1】:

在 MVVM 架构中,您不需要使用 Activity 的 onActivityResult 交换数据。相反,让目标 Activity 的 UI 绑定到 ViewModel 的 LiveData,后者进一步指向由另一个 Activity(通过其自己的 ViewModel)更新的相同数据源(例如 sqLite)。

【讨论】:

  • 我没有其他数据源。我从 Api 获取列表并将其显示在 RecyclerView 中。之后,我需要临时将另一个项目添加到用户添加的此列表中。这个元素将一直显示,直到我第一次关闭应用程序。但我也会将此项目发送到服务器并将其添加到列表中。下次用户打开应用时,他们会从 Api 中获得一个添加了新元素的列表。
  • 好的,我想你可以做到这一点。当您的 Activity 第一次需要数据时,其附加的 Viewmodel 会从 API(在初始化时)获取并更新 LiveData 对象,这些对象又会使用数据绑定更新 RecyclerView。稍后,当用户手动输入数据时,将此数据传递给 ViewModel 以调用 API。在 API 成功时,更新 LiveData 对象,该对象会自动使用新条目更新 RecyclerView。现在,如果您的流程有不同的 Activity 来添加新数据,我认为您应该将公共 ViewModel 附加到这两个 Activity 上。这样,无论导航流程如何,数据都会自动更新。
【解决方案2】:

MVVM 支持两种方式绑定。只需在完成或清除已覆盖其 onActivity 结果的活动时更新列表。

数据已在您之前的活动中订阅,并且会在其他活动更新列表时立即获取更新。 ViewModel 将在两个 Activity 之间共享。

看看 MVVM 与共享实例的工作情况:https://www.google.com/url?sa=t&source=web&rct=j&url=https://github.com/android/architecture-components-samples/issues/29&ved=2ahUKEwjn0ZWEzvPmAhUxzDgGHXhuBUsQFjAAegQICRAE&usg=AOvVaw36xQIOfJIp4abIODjXrz6S

【讨论】:

  • 这是不可能实现的。当第二个 Activity 传递数据并被销毁时,ViewModel 将调用 onCleared() 方法,第一个 Activity 将再次获取原始列表
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-28
  • 1970-01-01
  • 1970-01-01
  • 2019-06-25
  • 2021-05-31
相关资源
最近更新 更多