【问题标题】:LiveData doesn't update dataLiveData 不更新数据
【发布时间】:2020-02-21 19:37:58
【问题描述】:

我想请你帮忙。我正在编写一个使用 MVVM 和 LiveData 架构的应用程序。在 ViewPager 中,我有 3 个片段显示来自 ViewModel 的数据。而且我注意到,在将 viewModel 连接到 Activity 和 Fragment 之后,只有在 Activity 启动时才会更新数据,但是即使数据发生了变化,Observe 也不会更新数据。在向服务器调用下一个查询后,在 onDataSet 中,我发送适当的时间并从服务器获取 JSON 数据,然后解析并传递给 ViewModel。为什么 Fragment 一开始只更新一次数据,之后就什么都没有了?

这是托管片段的活动

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)
            }
        }

    }

这是 Activity 和 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)
   }

}

这就是在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
        })

    }

}

【问题讨论】:

    标签: android kotlin mvvm android-livedata


    【解决方案1】:

    您的 ViewModel 实例不正确。

    应该是

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

    在片段中:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-09
      • 2023-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多