I have MainActivity with NavigationDrawer, when I pressed "AddNewDevice" i would like to achieve Fragment called "AddNewDeviceFragment" with empty RecycledView. Then when i pressed "refreshButton" my RecycledView should be updated through LiveData.
Instead of this when I pressed button nothing happened. Looks like Live data observer doesn't work because If I add data by NewDeviceAdapter method called addDevice recycled view notify change.
My code below:
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"))
}
}
NewDeviceAdapter
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)
}
}
You are updating the newDevices inside addNewDevice function, but you don't update your LiveData anywhere. You must update allNewDevices, for example inside of addNewDevice function as bellow :
fun addNewDevice(newDevice: NewDevice) {
newDevices.add(newDevice)
allNewDevices.value = newDevices
}