如何通知数据集更改的多个活动和片段?

时间:2018-05-16 21:30:34

标签: android

考虑一个显示数据列表的Android应用,让用户深入了解它。在某些时候,用户会对需要在后端堆栈上的多个活动中反映的数据进行更改。实现这一目标的最佳模式是什么?

2 个答案:

答案 0 :(得分:3)

首先,让我们检查案例。

您的应用中有一个数据源。它的更新需要反映到多个UI,

  • 案例1:某些UI可能只需要整个数据源
  • 案例2:某些UI需要先在UI上显示之前处理数据

您需要以某种方式为所有UI创建单一的事实来源,并在发生事件时反映对它们的更改。

我使用Google新架构组件中的MVVMViewModel + LiveData在我的项目中解决了这个问题。为什么?因为它们是生命周期意识!您可以使用RxJava执行相同的操作。

1。 model layer

它是一个单例,并将数据源公开为LiveData A.在以下代码中,它将是OrderLiveStore.liveData

    class OrderLiveStore(
        private val orderStore: OrderStore
    ) {
        var liveData: MutableLiveData<List<Order>> = MutableLiveData()

        init {
            liveData.value =  orderStore.items
        }

    }

2。 view model layer

  • 案例1:您只需将该模型注入视图模型,并将LiveData A公开给视图。在考虑单例的事实下,连接到该视图模型的所有视图都将获得更新,因为视图模型只是从单例变量返回相同的属性。我使用dagger管理单身人士。

    class OrdersViewModel 
    @Inject constructor(
        orderLiveStore: OrderLiveStore
    ): ViewModel() {
    
        // expose to the view directly
        val orders: LiveData<List<Order>> = orderLiveStore.liveData
    
    }
    
  • 案例2:您仍然将模型注入视图模型,但在内部,您需要使用Transformations.map订阅它,并进行处理,并将结果公开给视图层

    class OrderViewModel(
        orderLiveStore: OrderLiveStore,
        private val orderId: String
    ) : ViewModel() {
    
        // expose to the view after processing it
        val order: LiveData<Order> = Transformations.map(orderLiveStore.liveData) {
            getNeededOrderFromList(it)
        }
    
        private fun getNeededOrderFromList(orderList: List<Order>?): Order? {
            // This method will be triggered every time orderStore.liveData gets updated
        }
    }
    

你可以看到,在案例1中,我使用匕首进行注射,因为它符合案例。在第2种情况下,我使用自定义参数在视图中创建了视图模型,因为视图模型需要一些额外的信息来从模型层中获取所需的部分。就我而言,它是orderId:String

3。 view layer

现在很简单,无论是片段还是活动,您都会观察到数据源并更新您的用户界面,

    orderViewModel.orders.observe(this, Observer {
        // update the ui
    })

或者更优雅的是,如果您不需要那么多的预处理,可以使用数据绑定将LiveData从视图模型直接绑定到xml

4。怎么样的CRUD

嗯,您只需直接更新model图层。但该动作将从2层中的一层开始

  • view图层(如果是来自用户)
  • view model图层(如果它是副作用)。

但即使它来自viewview仍会调用view model上的方法,而view model会调用模型图层上的某些方法,或者您只需更新它在视图模型层中取决于案例(因为你得到了单一的事实来源)。

  

它有点像Redux模式 - 几乎是单向数据流,每次更改都会在模型层发生并反射回视图模型层,然后冒泡到视图层。很容易推断出你的数据流。

5。结果将是你想要的。

因为现在所有内容都连接到单个事实源(共享模型层),但是以解耦的方式连接。每一层都有自己的工作。

6。还有一个提示

为了让Transformations.map生效,您需要在视图中observe结果,否则,来自Transformations.map的订阅将无效。

答案 1 :(得分:1)

您可以将您的共享数据放在Service中,然后在您的片段/活动onResume方法中,您可以从那里获取更新数据。

要更新当前的片段/活动,您可以在更新服务中的数据时触发事件,注册片段/活动以捕获它,从而更新显示的数据。您可以使用OttoBus来实现此目标