想要在使用通过 LatLon 的实时数据时为 textView 添加延迟

Want to add a delay for textView when using livedata that pass LatLon

正在使用 MutableLiveData 在服务与片段之间传递数据。 根据 Log.d 语句,数据被接收。 但是当我尝试使用 TextView 显示数据时,我得到了 null。它认为延迟会使它无效。有没有办法延迟或更新文本视图以便我可以显示数据?

DashbordFragment.kt

class DashbordFragment : Fragment() {

private var locationList = mutableListOf<LatLng>()
var liveLatLng = MutableLiveData<LatLng>()

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setHasOptionsMenu(true)
    sendActionCommandToService(Constants.ACTION_SERVICE_START)
}

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    observerTrackerService()
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.fragment_dashbord, container, false)
}
lateinit var binding : FragmentDashbordBinding
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    binding = FragmentDashbordBinding.bind(view)

    binding.btGotostation.setOnClickListener {

        startActivity(Intent(requireContext(),StationsActivity::class.java))
    }
    binding.btGotostatistics.setOnClickListener {
        findNavController().navigate(DashbordFragmentDirections.actionDashbordFragmentToStatisticsFragment())
    }

    binding.btGotolinediagram.setOnClickListener {
        findNavController().navigate(DashbordFragmentDirections.actionDashbordFragmentToLineDiagramFragment())
    }

    binding.btMap.setOnClickListener {
        findNavController().navigate(DashbordFragmentDirections.actionDashbordFragmentToMapsFragment())
    }
    binding.latlon.text = liveLatLng.value.toString()


}

override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
    inflater.inflate(R.menu.dashboard_menu, menu)
    super.onCreateOptionsMenu(menu, inflater)
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {

    return super.onOptionsItemSelected(item)
}

private fun observerTrackerService(){
    TrackerService.locationList.observe(viewLifecycleOwner) {

        if (it != null) {
            locationList = it
            Log.d("LocationList",locationList.toString())
        }
    }
    TrackerService.liveLatLng.observe(viewLifecycleOwner){

        Log.d("LiveLatLng", it.toString())
    }
    Log.d("LocationList", "Tester")

}
private fun sendActionCommandToService(action: String){
    Intent(
        requireContext(),
        TrackerService::class.java
    ).apply {
        this.action = action
        requireContext().startService(this)
    }
}

fragment_dashbord.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >


    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="top|center"
        android:text="@string/dashboard"
        android:textAlignment="center"
        android:textAppearance="@style/TextAppearance.AppCompat.Large" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/go_to_station"
        android:layout_marginStart="24dp"
        android:layout_marginTop="54dp"
        android:id="@+id/bt_gotostation"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/GoogleMap"
        android:layout_marginStart="24dp"
        android:layout_marginTop="140dp"
        android:id="@+id/btMap"/>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/statistics_desc"
        android:layout_marginTop="240dp"
        android:textAlignment="center"
        android:textAppearance="@style/TextAppearance.AppCompat.Medium" />


    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/development_bar_chart"
        android:layout_marginStart="24dp"
        android:layout_marginTop="290dp"
        android:id="@+id/bt_gotostatistics"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/development_line_diagram"
        android:layout_marginStart="24dp"
        android:layout_marginTop="360dp"
        android:id="@+id/bt_gotolinediagram"/>

    <TextView
        android:id="@+id/latlon"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:text="@string/statistics_desc"
        android:layout_marginTop="500dp"
        android:textAlignment="center"
        android:textAppearance="@style/TextAppearance.AppCompat.Medium" />

</FrameLayout>

您正在 onViewCreated 中设置它,它在您收到数据之前被调用。 相反,您可以在 onViewCreated 中如下设置观察者 示例:

liveLatLng.observe(this , Observer {
    it?.let{
        binding.latlon.text = it.toString()
    }
})

并设置值如下

TrackerService.liveLatLng.observe(viewLifecycleOwner){
    liveLatLng.value = it // hoping this is of type LatLng
}

注意:根据 android 开发文档

考虑这一点

Make sure to store LiveData objects that update the UI in ViewModel objects, as opposed to an activity or fragment, for the following reasons: To avoid bloated activities and fragments. Now these UI controllers are responsible for displaying data but not holding data state. To decouple LiveData instances from specific activity or fragment instances and allow LiveData objects to survive configuration changes.

来自 developer docs

这个binding.latlon.text = liveLatLng.value.toString()与livedata没有任何共同之处。正确使用时,您的代码应如下所示 binding.latlon = liveLatLng 并且无需延迟,LiveData 会为您完成。为此,您只需检查 LiveData, DataBinding and BindingAdapter.

所需绑定变量的小提示

<import type="com.google.type.LatLng" />

<variable
    name="latlon"
    type="androidx.lifecycle.MutableLiveData&lt;LatLng&gt;" />