集合的MutableLiveData

时间:2019-09-13 09:05:17

标签: kotlin collections mutablelivedata

我一堆一堆地从服务器请求数据,并将其存储在数组中。要跟踪下一批数据的获取,我拥有此类。在addItems方法中,我通知diffObservers并通过列表新项目:

class PackItems:MutableLiveData<ArrayList<GetPacksResponse.PackData>>() {
        private var diffObservers=ArrayList<Observer<List<GetPacksResponse.PackData>>>()
        private var active=false

        fun observeItems(owner: LifecycleOwner, valueObserver:Observer<List<GetPacksResponse.PackData>>,diffObserver:Observer<List<GetPacksResponse.PackData>>) {
            super.observe(owner,valueObserver)
            diffObservers.add(diffObserver)
        }

        override fun removeObservers(owner: LifecycleOwner) {
            super.removeObservers(owner)
            diffObservers= ArrayList()
        }

        fun addItems(toAdd:List<GetPacksResponse.PackData>) {
            value?.addAll(toAdd)
            if (active)
                for (observer in diffObservers)
                    observer.onChanged(toAdd)
        }

        override fun onActive() {
            super.onActive()
            active=true
        }

        override fun onInactive() {
            super.onInactive()
            active=false
        }
    }

问题是PackItemsMutableLiveData,公开它不是一个好习惯。是否可以将其转换为LiveData?通常我们会这样做:

private val _items = MutableLiveData<List<Int>>()
val items: LiveData<List<Int>> = _items


UPD :理想的情况是,我可以公开完全不变的LiveData。但是我不能只写

private val _packs:PackItems=PackItems()
val packs:LiveData<ArrayList<GetPacksResponse.PackData>>
get()=_packs

因为在这种情况下packs将不包含observeItems方法。因此必须有一个从LiveData派生的自定义类,例如:

open class PackItems: LiveData<ArrayList<GetPacksResponse.PackData>>() {
    protected var active=false
    protected var diffObservers = ArrayList<Observer<List<GetPacksResponse.PackData>>>()

    fun observeItems(owner: LifecycleOwner, valueObserver: Observer<List<GetPacksResponse.PackData>>, diffObserver: Observer<List<GetPacksResponse.PackData>>) {
        super.observe(owner,valueObserver)
        diffObservers.add(diffObserver)
    }
   //...
}

class MutablePackItems: PackItems() {
    fun addItems(toAdd:List<GetPacksResponse.PackData>) {
        value?.addAll(toAdd)
        if (active)
            for (observer in diffObservers)
                observer.onChanged(toAdd)
    }
}

但是在这种情况下,我将无法设置数据,因为现在MutablePackItems是LiveData(immutable):)

1 个答案:

答案 0 :(得分:2)

我会考虑使用合成代替继承:

class PackItems() {
    private val mutableData = MutableLiveData<ArrayList<GetPacksResponse.PackData>>()
    val asLiveData: LiveData<ArrayList<GetPacksResponse.PackData>> get() = mutableData
    ...

    fun observeItems(owner: LifecycleOwner, valueObserver:Observer<List<GetPacksResponse.PackData>>,diffObserver:Observer<List<GetPacksResponse.PackData>>) {
        mutableData.observe(owner,valueObserver)
        diffObservers.add(diffObserver)
    }

    fun removeObservers(owner: LifecycleOwner) {
        mutableData.removeObservers(owner)
        diffObservers = ArrayList()
    }

    // etc
}

编辑:将active设置为原始代码中的内容,可能会有点麻烦:

    private val mutableData = object : MutableLiveData<ArrayList<GetPacksResponse.PackData>>() {
        override fun onActive() {
            super.onActive()
            active = true
        }

        override fun onInactive() {
            super.onInactive()
            active = false
        }
    }

编辑2:

  

但是主要问题是我需要使用自定义LiveData方法返回自定义observeItems

重点是您不一定。每当您调用LiveData的方法(例如observe)时,只需调用items.asLiveData.observe(...)即可。如果要将其传递给接受foo的另一方法LiveData,请调用foo(items.asLiveData)

原则上,您可以可以通过扩展LiveData并将所有调用委托给mutableData来修改此方法:

class PackItems(): LiveData<ArrayList<GetPacksResponse.PackData>>() {
    private val mutableData = MutableLiveData<ArrayList<GetPacksResponse.PackData>>()
    ...

    fun observeItems(owner: LifecycleOwner, valueObserver:Observer<List<GetPacksResponse.PackData>>,diffObserver:Observer<List<GetPacksResponse.PackData>>) {
        mutableData.observe(owner,valueObserver)
        diffObservers.add(diffObserver)
    }

    override fun observe(owner: LifecycleOwner, observer: ArrayList<GetPacksResponse.PackData>) {
        mutableData.observe(owner, observer)
    }

    override fun removeObservers(owner: LifecycleOwner) {
        mutableData.removeObservers(owner) // not super!
        diffObservers = ArrayList()
    }

    // etc
}

但是我认为这不是一个好主意。