I have fragment which showing weather for 10 days with getting geolocation city and show exactly weather for this city for 10 days.
I have problem initialization with RecyclerView and Viewmodel.
Also I use Hilt to provide dependencies.
My goal is showing weather by location (already have permission) for 10 days.
import androidx.lifecycle.LiveData
import dagger.hilt.android.lifecycle.HiltViewModel
import db.entities.WeatherData
@HiltViewModel
interface ForecastViewmodel {
val dataforecast:LiveData<List<WeatherData>>
val city : LiveData<String>
val isRefreshing:LiveData<Boolean>
fun onRefresh()
}
@HiltViewModel
class ForecastViewmodelImpl(private val repository: ForecastRepository,
private val day: Day
) : ForecastViewmodel,
ViewModel(){
override val dataforecast = MutableLiveData<List<WeatherData>>()
override val city = MutableLiveData(day.city)
override val isRefreshing = MutableLiveData(true)
init {
loadForecast()
}
private fun loadForecast() {
isRefreshing.value = true
viewModelScope.launch {
try {
val data = repository.getForecast(day.days)
Timber.d("size is ${data}")
}catch (e:Exception){
Timber.e(e)
}
isRefreshing.value = false
}
}
override fun onRefresh() = loadForecast()
private fun Forecastday.toWeatherData() = WeatherData(
date = date,
temp = "${temp.roundToInt()}℃"
)
}
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.example.testtaskweatherappkevychsol.R
import db.entities.WeatherData
class WeatherRecView:RecyclerView.Adapter<WeatherRecView.WeatherHolder>() {
var listweather = emptyList<WeatherData>()
class WeatherHolder(view:View):RecyclerView.ViewHolder(view)
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): WeatherHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.daily_weather_layout,
parent,false)
return WeatherHolder(view)
}
override fun onBindViewHolder(
holder: WeatherHolder,
position: Int
) {
holder.itemView.findViewById<TextView>(R.id.Dateitem).text = listweather[position].date
holder.itemView.findViewById<TextView>(R.id.tempitem).text = listweather[position]
.temp.toString()
}
override fun getItemCount(): Int {
return listweather.size
}
fun addlistintoUI(list: List<WeatherData>){
listweather = list
}
}
data class WeatherData(
val temp:String,
val date:String
)
import RecyclerView.WeatherRecView
import Viewmodel.ForecastViewmodel
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.testtaskweatherappkevychsol.R
import com.example.testtaskweatherappkevychsol.databinding.FragmentWeatherBinding
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class WeatherAtTheLifeMomentFragment : Fragment(R.layout.fragment_weather){
lateinit var recview:WeatherRecView
private var binding : FragmentWeatherBinding? = null
lateinit var viewmodel:ForecastViewmodel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val binding = FragmentWeatherBinding.inflate(inflater,container,false)
this.binding = binding
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
with(binding){
this!!.refreshbt.setOnClickListener { viewmodel.isRefreshing }
containerlistweather.adapter = recview
containerlistweather.addItemDecoration(DividerItemDecoration(containerlistweather.context,
(containerlistweather
.layoutManager as LinearLayoutManager).orientation))
with(viewmodel){
dataforecast.observe(viewLifecycleOwner) { recview.listweather = it }
City.text = city.toString()
}
}
}
override fun onDestroyView() {
super.onDestroyView()
binding = null
}
}
CodePudding user response:
lateinit property recview has not been initialized
you are getting this issue as you are trying to access lateinit property recview
without initialising it
in WeatherAtTheLifeMomentFragment
From
containerlistweather.adapter = recview
To
recview = WeatherRecView() // initialise recview variable by creating instance of your adapter
containerlistweather.layoutManager = LinearLayoutManager(context) // not sure you have set layout manager in your xml so just adding it in your code as it is necessary to use
containerlistweather.adapter = recview
Also you have create method addlistintoUI
in WeatherRecView
class so use it and make below mentioned changes to load your data
in WeatherAtTheLifeMomentFragment
class
From
dataforecast.observe(viewLifecycleOwner) { recview.listweather = it }
To
dataforecast.observe(viewLifecycleOwner) { recview.addlistintoUI(it) }
in WeatherRecView
class
From
fun addlistintoUI(list: List<WeatherData>){
listweather = list
}
To
fun addlistintoUI(list: List<WeatherData>){
listweather.addAll(list)
notifyDataSetChanged()
}
```