0

我逐束从服务器请求数据并将其存储在数组中。为了跟踪下一组数据的获取,我有这个类。在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) :)

4

1 回答 1

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:

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

关键是你不一定。每当您调用LiveData's 方法(例如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
}

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

于 2019-09-13T10:50:10.693 回答