简体   繁体   English

LiveData 不更新数据

[英]LiveData doesn't update data

I would like to ask you for help.我想请你帮忙。 I am writing an application that uses MVVM and LiveData architecture.我正在编写一个使用 MVVM 和 LiveData 架构的应用程序。 Inside ViewPager I have 3 fragments displaying data that comes from ViewModel.在 ViewPager 中,我有 3 个片段显示来自 ViewModel 的数据。 And I noticed that after connecting the viewModel to the activity and to the fragment, the data is updated only when the activity is started, but then Observe does not update the data even though the data has changed.而且我注意到在将 viewModel 连接到活动和片段后,数据仅在活动启动时更新,但即使数据已更改,Observe 也不会更新数据。 After calling the next query to the server, inside onDataSet I send the appropriate time and obtains JSON data from the server, which it parses and passes to ViewModel.在向服务器调用下一个查询后,在 onDataSet 中,我发送适当的时间并从服务器获取 JSON 数据,它解析并传递给 ViewModel。 Why Fragment updates data only once in the beginning and nothing changes after?为什么 Fragment 一开始只更新一次数据,之后没有任何变化?

This is the activity that hosts the fragments这是承载片段的活动

class MainActivity : AppCompatActivity(), DatePickerDialog.OnDateSetListener {

    private lateinit var currencyViewModel: CurrencyViewModel
    private lateinit var viewPager: ViewPager2
    private lateinit var tabLayout: TabLayout
    private lateinit var navigationView: NavigationView
    private lateinit var floatingActionButton: FloatingActionButton

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val fm = supportFragmentManager

        currencyViewModel = ViewModelProvider
            .AndroidViewModelFactory(application)
            .create(CurrencyViewModel::class.java)

        viewPager = findViewById(R.id.viewPager)
        tabLayout = findViewById(R.id.tabLayout)
        navigationView = findViewById(R.id.navigationView)
        floatingActionButton = findViewById(R.id.floatingActionButton)

        val viewPagerAdapter = CurrencyViewPagerAdapter(this)
        viewPager.adapter = viewPagerAdapter

        TabLayoutMediator(tabLayout
            ,viewPager
            ,TabLayoutMediator.TabConfigurationStrategy {
                    tab, position ->
                when(position){
                    0 -> tab.text = "Tabela A"
                    1 -> tab.text = "Tabela B"
                    2 -> tab.text = "Tabela C"
                }
            }).attach()
        floatingActionButton.setOnClickListener {
            val dialog = CalendarFragment()
            dialog.show(fm, "DatePickerDialog")
        }
    }
    override fun onDateSet(view: DatePicker?, year: Int, month: Int, dayOfMonth: Int) {
        //Convert year,month,day to millisecounds
        val c = Calendar.getInstance()
        c.set(year,month,dayOfMonth)
        val dayInMillis = c.time.time
        val today = Calendar.getInstance()

        if(checkIsDateAfterToday(today, c)){
            CoroutineScope(Dispatchers.Main).launch {
                currencyViewModel.setTableA(dayInMillis)
            }
        }

    }

This is ViewModel common for activity and fragment这是活动和片段常见的 ViewModel

class CurrencyViewModel : ViewModel() {

    private val repository = CurrencyRepository()
    val tableA: MutableLiveData<Array<TableA>> by lazy {
        MutableLiveData<Array<TableA>>().also {
            loadTableA(Date().time)
        }
    }

    private fun loadTableA(time: Long) {
            CoroutineScope(Dispatchers.Main).launch {
               val loadedData = CoroutineScope(Dispatchers.IO).async {
                    repository.getTableA(time)
                }.await()
                tableA.value = loadedData
            }
    }

   fun setTableA(time: Long){
       loadTableA(time)
   }

}

And that's the fragment which displays data in recyclerView这就是在 recyclerView 中显示数据的片段

class TableAFragment : Fragment() {

    private lateinit var currencyViewModel: CurrencyViewModel
    private lateinit var recyclerViewA: RecyclerView

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {

        return inflater.inflate(R.layout.fragment_table_a, container, false)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        currencyViewModel = ViewModelProvider.AndroidViewModelFactory
            .getInstance(requireActivity().application)
            .create(CurrencyViewModel::class.java)

    }

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

        recyclerViewA = view.findViewById(R.id.recyclerView_A)
        recyclerViewA.layoutManager = LinearLayoutManager(requireContext())

        currencyViewModel.tableA.observe(viewLifecycleOwner, androidx.lifecycle.Observer{
            val nbpAdapter = NBPAdapter(it)
            recyclerViewA.adapter = nbpAdapter
        })

    }

}

Your instantiation of ViewModel is incorrect.您的 ViewModel 实例化不正确。

Should be应该

currencyViewModel = ViewModelProvider(this).get<CurrencyViewModel>() // lifecycle-ktx

and in Fragment:并在片段中:

currencyViewModel = ViewModelProvider(requireActivity()).get<CurrencyViewModel>() // lifecycle-ktx

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM