Android 为什么当我在适配器中添加数据时,它也会更改我的LiveData?

Android 为什么当我在适配器中添加数据时,它也会更改我的LiveData?,android,kotlin,android-livedata,android-architecture-components,android-jetpack,Android,Kotlin,Android Livedata,Android Architecture Components,Android Jetpack,所以我对使用体系结构组件的MVVM是新手。我想在我的回收器视图中添加加载页脚。在适配器中添加虚拟项以便在适配器中显示加载页脚后,我不明白为什么虚拟项(餐厅)也会出现在我的LiveData流中(在我的repository和RestaurantClient中,来自改装),我假设适配器和我的LiveData流之间没有连接 这是我的适配器 class RestaurantRecyclerAdapter(var mOnItemClickedListener : OnItemClickedListener)

所以我对使用体系结构组件的MVVM是新手。我想在我的回收器视图中添加加载页脚。在适配器中添加虚拟项以便在适配器中显示加载页脚后,我不明白为什么虚拟项(餐厅)也会出现在我的LiveData流中(在我的repository和RestaurantClient中,来自改装),我假设适配器和我的LiveData流之间没有连接

这是我的适配器

class RestaurantRecyclerAdapter(var mOnItemClickedListener : OnItemClickedListener): RecyclerView.Adapter<RecyclerView.ViewHolder>() {


    private val ITEM_TYPE = 0
    private val LOADING_TYPE = 1

    var restaurantList =  ArrayList<Restaurant>()

    override fun getItemViewType(position: Int): Int {
        if ( restaurantList[position].name == "dummy" ) {
            return LOADING_TYPE
        } else {
            return ITEM_TYPE
        }
    }




    fun addLoadingFooter() {

        if (!isLoading) {
            isLoading = true

            val dummyRestaurant = Restaurant()
            dummyRestaurant.name = "dummy"
            restaurantList.add(dummyRestaurant)
            notifyDataSetChanged()
        }
    }

    fun removeLoadingFooter() {

        isLoading = false

        val index = restaurantList.indexOfFirst{
            it.name == "dummy"
        }

        if (index != -1) {
            restaurantList.removeAt(index)
            notifyDataSetChanged()
        }


    }
类RestaurantRecyclerAdapter(var mOnItemClickedListener:OnItemClickedListener):RecyclerView.Adapter(){
私有val项_类型=0
专用val加载类型=1
var restaurantList=ArrayList()
覆盖getItemViewType(位置:Int):Int{
如果(餐厅列表[position].name==“dummy”){
返回加载类型
}否则{
返回项目类型
}
}
乐趣添加加载页脚(){
如果(!isLoading){
isLoading=true
val Dummy餐厅=餐厅()
dummy restaurant.name=“dummy”
restaurantList.add(dummyRestaurant)
notifyDataSetChanged()
}
}
有趣的电影{
isLoading=错误
val索引=restaurantList.indexOfFirst{
it.name==“虚拟”
}
如果(索引!=-1){
restaurantList.removeAt(索引)
notifyDataSetChanged()
}
}
当recycler视图到达底部时,它将触发此代码从服务器重新提取数据,这也是我的片段中列表的观察者

class RestaurantListFragment : Fragment(), OnItemClickedListener {

    lateinit var model : RestaurantListViewModel
    lateinit var restaurantRecyclerAdapter: RestaurantRecyclerAdapter


    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment

        fragmentView = inflater.inflate(R.layout.fragment_restaurant_list, container, false)
        model = ViewModelProvider(this).get(RestaurantListViewModel::class.java)

        recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {

            override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                super.onScrollStateChanged(recyclerView, newState)

                val isLoading = model.isLoading.value ?: return
                val isQueryExhausted = model.isQueryHausted.value ?: return


                if (!recyclerView.canScrollVertically(1) && !isLoading && !isQueryExhausted) {

                    model.searchNextPage() 
                    restaurantRecyclerAdapter.addLoadingFooter() // <-- add footer in here
                }
            }

        })


        model.restaurants.observe(viewLifecycleOwner, Observer { restaurantList ->

            // that dummy restaurant object I add from adapter to show loading footer
            // will also show in my LiveData in 'restaurantList' in here


            restaurantList?.let {

                restaurantRecyclerAdapter.setRestaurants(it)
                restaurantRecyclerAdapter.removeLoadingFooter() // remove footer in here
                showLoadingIndicator(false)

            }

        })


        return fragmentView
    }


}
class RestaurantListFragment:Fragment(),OnItemClickedListener{
lateinit var模型:RestaurantListViewModel
lateinit var restaurantRecyclerAdapter:restaurantRecyclerAdapter
覆盖创建视图(
充气器:布局充气器,容器:视图组?,
savedInstanceState:捆绑?
):查看{
//为该碎片膨胀布局
fragmentView=充气机。充气(R.layout.fragment\u餐厅\u列表,容器,错误)
model=ViewModelProvider(this.get)(RestaurantListViewModel::class.java)
recyclerView.addOnScrollListener(对象:recyclerView.OnScrollListener(){
覆盖CrollStateChanged(recyclerView:recyclerView,newState:Int){
super.onScrollStateChanged(recyclerView、newState)
val isLoading=model.isLoading.value?:返回
val isqueryexhousted=model.isqueryhousted.value?:返回
如果(!recyclerView.CanScrollVertical(1)&&&!isLoading&&!IsQueryExhousted){
model.searchNextPage()
restaurantRecyclerAdapter.addLoadingFooter()//
//我从适配器添加的虚拟餐厅对象显示加载页脚
//也将显示在我的LiveData中的“restaurantList”中
餐厅名单?让我看看{
restaurantRecyclerAdapter.setRestaurants(it)
restaurantRecyclerAdapter.removeLoadingFooter()//删除此处的页脚
显示加载指示器(错误)
}
})
返回碎片视图
}
}
下面是该片段的viewModel

class RestaurantListViewModel : ViewModel() {

    var restaurants : LiveData<ArrayList<Restaurant>> = RestaurantRepository.restaurants

    fun searchRestaurants(query: String) {


        RestaurantRepository.searchRestaurants(
            query = query,
            latitude = mLatitude,
            longitude = mLongitude
        )
    }

    fun searchNextPage() {

        RestaurantRepository.searchNextPage(mLatitude,mLongitude)

    }




}
class RestaurantListViewModel:ViewModel(){
var restaurants:LiveData=RestaurantRepository.restaurants
趣味搜索餐厅(查询:字符串){
餐馆(
query=query,
纬度=纬度,
经度=米长
)
}
趣味搜索下一页(){
RestaurantRepository.SearchNext页面(mLatitude,mLongitate)
}
}
这是我的存储库

object RestaurantRepository {

    val restaurants: MediatorLiveData<ArrayList<Restaurant>> = MediatorLiveData()
    private val restaurantsFromClient : LiveData<ArrayList<Restaurant>> = RestaurantClient.restaurants

    init {
        initMediators()
    }

    private fun initMediators() {

        restaurants.addSource(restaurantsFromClient) { restaurantList ->

            if (restaurantList == null) {
                // get data from Room database
            } else {
                restaurants.postValue(restaurantList)
            }


        }

    }


    fun searchNextPage(latitude:Double, longitude: Double) {

        val numberOfCurrentShowedRestaurants = restaurants.value?.size ?: return

        RestaurantClient.searchRestaurants(
            query = mQuery,
            latitude = latitude,
            longitude = longitude,
            start = numberOfCurrentShowedRestaurants + NUMBER_OF_DOCUMENT_PER_PAGE
        )



    }

}
objectrestaurantrepository{
val:MediatorLiveData=MediatorLiveData()
private val restaurantsFromClient:LiveData=RestaurantClient.restaurants
初始化{
initMediators()
}
私人调解人(){
addSource(restaurantsFromClient){restaurantList->
如果(restaurantList==null){
//从房间数据库获取数据
}否则{
餐厅.postValue(餐厅列表)
}
}
}
趣味搜索下一页(纬度:双精度,经度:双精度){
val numberOfCurrentShowedRestaurants=餐厅。值?大小?:返回
RestaurantClient.searchRestaurants(
query=mQuery,
纬度=纬度,
经度=经度,
开始=当前显示的Restarants数量+每页文档数量
)
}
}
这是一个餐馆客户端,它使用改型从服务器检索数据

object RestaurantClient {

    val restaurants = MutableLiveData<ArrayList<Restaurant>>()

    private val restaurantService = RetrofitServiceGenerator.getInstance(RestaurantAPI::class.java)

    fun searchRestaurants(query: String, latitude:Double, longitude: Double, start: Int) {

        val call = restaurantService.searchRestaurants(
            radius = 2000,
            query = query,
            latitude = latitude,
            longitude = longitude,
            start = start,
            count = NUMBER_OF_DOCUMENT_PER_PAGE
        )

        isLoading.value = true

        call.enqueue(object: Callback<RestaurantListBaseResponse> {

            override fun onFailure(call: Call<RestaurantListBaseResponse>, t: Throwable) {

            }

            override fun onResponse(call: Call<RestaurantListBaseResponse>, response: Response<RestaurantListBaseResponse>) {

                isLoading.postValue(false)

                if (response.isSuccessful) {

                    val bodyResponse = response.body() ?: return

                    val listOfRestaurants = bodyResponse.restaurants
                    val restos = ArrayList<Restaurant>()

                    for (i in listOfRestaurants ) {
                        restos.add(i.restaurant)
                    }


                    if (start == 0) {
                        restaurants.postValue(restos)

                    } else {
                        restaurants.value?.let {
                            val newRestaurants = it

                            for (i in listOfRestaurants ) {
                                newRestaurants.add(i.restaurant)
                            }

                            restaurants.postValue(newRestaurants)

                        }

                    }


            }

        })


    }




}
对象RestaurantClient{
val=MutableLiveData()
private val restaurantService=RefughtServiceGenerator.getInstance(RestaurantAPI::class.java)
有趣的搜索餐厅(查询:字符串、纬度:双精度、经度:双精度、起点:Int){
val call=restaurantService.searchRestaurants(
半径=2000,
query=query,
纬度=纬度,
经度=经度,
开始=开始,
计数=每页文档的数量
)
isLoading.value=true
排队(对象:Callback{
覆盖失效时的乐趣(调用:调用,t:可丢弃){
}
覆盖fun onResponse(调用:调用,响应:响应){
isLoading.postValue(false)
if(response.issucessful){
val bodyResponse=response.body()?:返回
val listOfRestaurants=bodyResponse.restaurants
val restos=ArrayList()
对于(我在员工名单中){
restos.add(即餐厅)
}
如果(开始==0){
餐厅。后价值(restos)
}否则{
休息