RecyclerView 适配器不通知 DataSetChanged

RecycledView adapter doesnt notify DataSetChanged

我有 MainActivityNavigationDrawer,当我按下 "AddNewDevice" 我想用空 RecycledView 实现名为 "AddNewDeviceFragment" 的片段。然后当我按下 "refreshButton" 时,我的 RecycledView 应该通过 LiveData.[=15 更新=]

当我按下按钮时没有发生任何事情,而不是这个。看起来实时数据观察器不起作用,因为如果我通过 NewDeviceAdapter 方法添加数据,调用 addDevice 回收视图通知更改。

我的代码如下:

MainActivity

lateinit var auth: FirebaseAuth
lateinit var toolbar: Toolbar
lateinit var drawerLayout: DrawerLayout
lateinit var navView: NavigationView

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    auth = FirebaseAuth.getInstance()

    toolbar = findViewById(R.id.toolbar)
    setSupportActionBar(toolbar)

    drawerLayout = findViewById(R.id.drawer_layout)
    navView = findViewById(R.id.nav_view)

    val toggle: ActionBarDrawerToggle = ActionBarDrawerToggle(this, drawerLayout, toolbar, 0, 0)
    drawerLayout.addDrawerListener(toggle)
    toggle.syncState()
    navView.setNavigationItemSelectedListener(this)

    supportFragmentManager.beginTransaction().replace(R.id.content_layout,
        AllDevicesFragment()
    ).commit()
    navView.setCheckedItem(R.id.nav_allDevices)
    Validator.validateInternetConnection(baseContext)

}

override fun onBackPressed() {
    if(supportFragmentManager.backStackEntryCount == 0){
        supportFragmentManager.popBackStack()
    } else {
        super.onBackPressed()
    }
}

override fun onNavigationItemSelected(item: MenuItem): Boolean {
    updateHeader()

    var fragment : Fragment = Fragment()
    item.setChecked(true)

    when (item.itemId) {
        R.id.nav_profile -> {
            fragment = ProfileFragment()
        }
        R.id.nav_allDevices -> {
            fragment = AllDevicesFragment()
        }
        R.id.nav_addNewDevice -> {
            fragment = AddNewDeviceFragment()
        }
        R.id.nav_contact -> {
            fragment = ContactFragment()
        }
        R.id.nav_updateUser -> {
            fragment = UpdateUserFragment()
        }
        R.id.nav_logout -> {
            auth.signOut()
            finish()
            startActivity(Intent(this, LoginActivity::class.java))
        }
    }

    supportFragmentManager
        .beginTransaction()
        .replace(R.id.content_layout,fragment)
        .addToBackStack("fragments")
        .commit()

    drawerLayout.closeDrawer(GravityCompat.START)
    return true
}

fun updateHeader(){

    //TODO Zrobić tak żeby aktualizowało header jak się otwiera navigation drawer

    var username : TextView = navView.getHeaderView(0).findViewById(R.id.navUsername)
    var email : TextView = navView.getHeaderView(0).findViewById(R.id.navEmmailAddres)
    var profilePicture : ImageView = navView.getHeaderView(0).findViewById(R.id.navProfilePicture)

    username.setText(auth.currentUser?.displayName)
    email.setText(auth.currentUser?.email)
    Glide.with(this)
        .load(auth.currentUser?.photoUrl)
        .into(profilePicture)
}

AddNewDeviceFragment

class AddNewDeviceFragment : Fragment() {

    private var newDevices: MutableList<NewDevice> = arrayListOf()
    private var adapter: NewDeviceAdapter = NewDeviceAdapter(arrayListOf())
    private lateinit var model: NewDeviceViewModel
    private lateinit var rootView: View

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        rootView = inflater.inflate(R.layout.fragment_addnewdevice, container, false)

        return rootView
    }

    override fun onStart() {
        super.onStart()


        var newDevicesRecycledView = rootView.findViewById(R.id.newDevicesRecycledView) as RecyclerView
        newDevicesRecycledView.layoutManager = LinearLayoutManager(activity)
        newDevicesRecycledView.adapter = adapter

        //ViewModel
        model = ViewModelProviders.of(this).get(NewDeviceViewModel::class.java)

        //LiveData
        model.getNewDevices().observe(viewLifecycleOwner, Observer<MutableList<NewDevice>> { newDevices ->
            adapter.addDevice(newDevices)
        })

        refreshButton.setOnClickListener{addToRecycledView()}
    }

    fun addToRecycledView(){
        model.addNewDevice(NewDevice("10.121.125.57"))
    }
}

新设备适配器

package com.example.lightmeup.NewDevice

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.example.lightmeup.Entity.NewDevice
import com.example.lightmeup.R

class NewDeviceAdapter(var newDevices: MutableList<NewDevice>):     RecyclerView.Adapter<NewDeviceViewHolder>() {


    //number of items
    override fun getItemCount(): Int {
       return newDevices.size
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NewDeviceViewHolder {
        val layoutInflater = LayoutInflater.from(parent.context)
        val cellForRow = layoutInflater.inflate(R.layout.device_in_acces_point_state_item, parent ,false)
        return NewDeviceViewHolder(cellForRow)
    }

    override fun onBindViewHolder(holder: NewDeviceViewHolder, position: Int) {
        holder.bind(newDevices[position])
    }

    fun addDevice( data: MutableList<NewDevice>){
        this.newDevices = data
        notifyDataSetChanged()
    }
}

NewDeviceViewHolder

package com.example.lightmeup.NewDevice

import android.view.View
import androidx.recyclerview.widget.RecyclerView
import com.example.lightmeup.Entity.NewDevice
import kotlinx.android.synthetic.main.device_in_acces_point_state_item.view.*

class NewDeviceViewHolder(val view: View): RecyclerView.ViewHolder(view){

    fun bind(newDevice: NewDevice) = with(view){
        device_name.text = newDevice.name
    }
}

NewDeviceViewModel

package com.example.lightmeup.NewDevice

import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MutableLiveData
import com.example.lightmeup.Entity.NewDevice

class NewDeviceViewModel(application: Application) : AndroidViewModel(application) {

    val allNewDevices: MutableLiveData<MutableList<NewDevice>> by lazy {MutableLiveData<MutableList<NewDevice>>()}
    val newDevices: MutableList<NewDevice> = arrayListOf()

    init {
        addNewDevice(NewDevice("JAJko"))
    }

    fun getNewDevices(): MutableLiveData<MutableList<NewDevice>>{
        return allNewDevices
    }

    fun addNewDevice(newDevice: NewDevice) {
        newDevices.add(newDevice)
    }
}

您的实时数据从未更新,因为您的视图模型仅将新数据添加到列表而不是实时数据。所以你的代码中应该有这一行。

fun addNewDevice(newDevice: NewDevice) {
    newDevices.add(newDevice)
    allNewDevices.value = newDevices
}

您正在 addNewDevice 函数内更新 newDevices,但您没有在任何地方更新 LiveData。您必须更新 allNewDevices,例如在 addNewDevice 函数内部,如下所示:

    fun addNewDevice(newDevice: NewDevice) {
        newDevices.add(newDevice)
        allNewDevices.value = newDevices
    }