Reputation: 27
I am only able to display the last child in myCars
into a recyclerView but I am not sure how i tried using for loop but i am not sure if that is the right way to write it
this is my code for GpsFragment.kt
i tried to display my data here and i got an error which is
lateinit property cars has not been initialized
class GpsFragment : Fragment(), OnCarItemClickListener {
private var user = FirebaseAuth.getInstance().currentUser
val reqId = user!!.uid
lateinit var cars: List<Cars>
private val ref = FirebaseDatabase.getInstance().reference.child("users")
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
(context as AppCompatActivity).supportActionBar!!.title = "Gps"
val root = inflater.inflate(R.layout.fragment_gps, container, false)
return root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
addCarbtn.setOnClickListener {
val intent = Intent(activity, AddCarActivity::class.java)
activity?.startActivity(intent)
}
cars = emptyList()
var adapter = CarAdapter(cars, this)
myCarlist?.adapter = adapter
showCars()
}
private fun showCars() {
var carLat:String
var carLng:String
var name:String
val query = ref.orderByChild("uid").equalTo(reqId)
query.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onCancelled(p0: DatabaseError) {
}
override fun onDataChange(dataSnapshot: DataSnapshot) {
for (childDss in dataSnapshot.children) {
for (subChildren in childDss.child("myCars").children){
val count = childDss.child("myCars").childrenCount.toInt()
carLat = (subChildren.child("carlat").getValue(String::class.java)).toString()
carLng = (subChildren.child("carlng").getValue(String::class.java)).toString()
name = (subChildren.child("carid").getValue(String::class.java)).toString()
Log.d("carlat",carLat.toString())
Log.d("carlng",carLng.toString())
Log.d("name",name.toString())
cars = listOf(
Cars(name.toString(), carLat.toString(), carLng.toString())
)
}
}
myCarlist?.layoutManager = LinearLayoutManager(activity)
myCarlist?.adapter = CarAdapter(cars,this@GpsFragment)
myCarlist.adapter?.notifyDataSetChanged()
}
})
}
override fun onItemClick(cars: Cars, position: Int) {
val intent = Intent(context, TrackingActivity::class.java)
intent.putExtra("CARNAME", cars.name)
intent.putExtra("LAT", cars.latitude)
intent.putExtra("LNG", cars.longtitude)
startActivity(intent)
}
}
This is my code for Cars.kt
data class Cars(val name: String = "-",
val latitude: String = "-",
val longtitude: String = "-")
This is my code for CarAdapter.kt
class CarAdapter (private val cars : List<Cars>, var clickListener: OnCarItemClickListener) : RecyclerView.Adapter<CarAdapter.CarViewHolder>(){
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CarViewHolder {
val inflater = LayoutInflater.from(parent.context).inflate(R.layout.list_layout, parent, false)
return CarViewHolder(inflater)
}
override fun getItemCount() = cars.size
override fun onBindViewHolder(holder: CarViewHolder, position: Int) {
val car = cars[position]
holder.initialize(cars.get(position),clickListener)
}
class CarViewHolder(val view:View) : RecyclerView.ViewHolder(view){
var carName = view.carname
var lat = view.latitude
var lng = view.longtitude
fun initialize(cars: Cars, action:OnCarItemClickListener){
carName.text = cars.name
lat.text = cars.latitude
lng.text = cars.longtitude
view.setOnClickListener{
action.onItemClick(cars, adapterPosition)
}
}
}
}
interface OnCarItemClickListener{ fun onItemClick(cars: Cars, position: Int) }
Upvotes: 0
Views: 213
Reputation: 80904
Firebase api is asynchronous, therefore when you are calling myCarlist?.adapter = CarAdapter(cars,this)
is it getting called before the data is retrieved from the database, and since you are initializing cars
inside the for loop, then you get the above error that it is not initialised yet. Therefore to solve this, you need to set the adapter inside onDataChange()
:
override fun onDataChange(dataSnapshot: DataSnapshot) {
if (dataSnapshot.exists())
{
for (childDss in dataSnapshot.children){
val count = childDss.child("myCar").childrenCount.toInt()
Log.d("count",count.toString())
for (i in 0 until count){
val carLat = childDss.child("carlat").getValue(String::class.java)
val carLng = childDss.child("carlng").getValue(String::class.java)
val name = childDss.child("carid").getValue(String::class.java)
cars = listOf(
Cars(name.toString(),carLat.toString(),carLng.toString())
)
}
myCarlist?.adapter = CarAdapter(cars,this)
}
}
}
Upvotes: 1