想在使用Latlon的Livedata时添加textView的延迟

发布于 2025-01-31 13:39:11 字数 4923 浏览 3 评论 0原文

使用MutableLiveData将服务之间的数据传递给片段。 根据日志。 但是,当我尝试使用TextView显示数据时,我会毫无用处。它认为延迟使其无效。有没有办法延迟或更新文本视图,以便我可以显示数据?

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>

Are passing data between a service to a fragment using a MutableLiveData.
Accordenly to a Log.d statement the data is recived.
But when i try to use TextView to display the data i get null. It think a delay makes it null. Is there a way to delay or update the textview so i can display the data?

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>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

花海 2025-02-07 13:39:11

您正在用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 Dev Docs考虑

确保存储更新UI的Livedata对象
与活动或碎片相对的对象,以下
原因:避免活动和碎片。现在这些UI
控制器负责显示数据,但不持有数据
状态。将寿命的实例与特定活动或
片段实例,允许生命的对象生存在配置中
更改。

来自开发人员文档

You are setting this in onViewCreated which is called earlier than you received the data.
Instead you can set an observer as follows in onViewCreated
example :

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

and set the value as follows

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

Note: Consider this according to android dev docs

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.

from developer docs

葮薆情 2025-02-07 13:39:11

binding.latlon.text = livelatlng.value.tostring()与livedata没有任何共同点。正确使用时,您的代码应该看起来像binding.latlon = livelatlng,并且无需延迟,livedata将为您做。要达到这一点,您需要的只是检查 livedata> livedata databinding and bindingAdapter

小提示,用于所需的绑定变量

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

<variable
    name="latlon"
    type="androidx.lifecycle.MutableLiveData<LatLng>" />

This binding.latlon.text = liveLatLng.value.toString() has nothing in common with livedata. When used correctly, your code should look like this binding.latlon = liveLatLng and no need for delay, LiveData will do it for you. To reach this all you need is to check LiveData, DataBinding and BindingAdapter.

Small hint for required binding variable

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

<variable
    name="latlon"
    type="androidx.lifecycle.MutableLiveData<LatLng>" />
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文