Преобразование типов из data класса в recyclerView
Имеется JSON response:
{
"response" : [
{
"f_name" : "иВан",
"l_name" : "ИваноВ",
"birthday" : "1987-03-23",
"specialty" : [{
"specialty_id" : 101,
"name" : "Менеджер"
}]
},
{
"f_name" : "Петр",
"l_name" : "петроВ",
"birthday" : null,
"specialty" : [{
"specialty_id" : 101,
"name" : "Менеджер"
}]
}
]
}
и соответствующий data class в модели:
data class Response(
@SerializedName("avatr_url")
val avatrUrl: String,
val birthday: String,
@SerializedName("f_name")
val fName: String,
@SerializedName("l_name")
val lName: String,
val specialty: List<Specialty>
)
Требуется вывести список всех профессий в RecyclerView, в классе ViewModel делаю transformation.map для полученной liveData:
class SpecialtyListViewModel : ViewModel() {
val employeesInfo = liveData {
val data = Employee.repository.getEmployeesInfo()
emit(data)
}
val specialties = Transformations.map(employeesInfo) {
it.response
}
val specialtyList = Transformations.map(specialties) {
it[0]
}
}
Во фрагменте подписываюсь на liveData и вызываю адаптер RecyclerView, в который нужно добавить аргументом приведенный тип liveData именно для specialtyList:
class SpecialtyListFragment : Fragment(), SpecialtyListAdaapter.Listener {
companion object {
fun newInstance() = SpecialtyListFragment()
}
private lateinit var viewModel: SpecialtyListViewModel
lateinit var specialtyListAdaapter: SpecialtyListAdaapter
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
viewModel = ViewModelProvider(this).get(SpecialtyListViewModel::class.java)
val root = inflater.inflate(R.layout.specialty_list_fragment, container, false)
root.specialtyListRecyclerView.layoutManager = LinearLayoutManager(context)
viewModel.specialties.observe(viewLifecycleOwner, Observer {
specialtyListAdaapter = SpecialtyListAdaapter(it, this)
specialtyListRecyclerView.adapter = specialtyListAdaapter
})
return root
}
}
Получаю от IDE ошибку приведения типов:
Type mismatch.
Required:
List<Specialty>
Found:
List<Response>!
В данном случае сам класс Response является Listом, а поле name является элементом списка specialty вложенного в каждый элемент списка Response. Хотелось бы выяснить как корректно сформировать список для передачи??...Может через map или же к примеру нужно создать новый список, обращаясь к liveDate , например:
fillSpecialtyList(): List<Specialty> {
val specialtyList = arrayListOf<Specialty>()
for (....)
return specialtyList
}
???
Ответы (2 шт):
Т.е. получается класс EmployeesInfo это список типа Response:
{
"response" : [
{
"f_name" : "иВан",
"l_name" : "ИваноВ",
"birthday" : "1987-03-23",
"specialty" : [{
"specialty_id" : 101,
"name" : "Менеджер"
}]
},
{
"f_name" : "Петр",
"l_name" : "петроВ",
"birthday" : null,
"specialty" : [{
"specialty_id" : 101,
"name" : "Менеджер"
}]
}
]
}
А в конструкторе класса Response есть поле specialty являющееся судя по квадратным скобкам тоже списком (в нем 1-й элемент specialty_id, 2-й name). А мне нужно как раз сформировать список из этих name из всех объектов массива Response и дать их адаптеру, чтоб они в RecyclerView отобразились..
data class Response(
@SerializedName("avatr_url")
val avatrUrl: String,
val birthday: String,
@SerializedName("f_name")
val fName: String,
@SerializedName("l_name")
val lName: String,
val specialty: List<Specialty>
)
data class Specialty(
val name: String,
@SerializedName("specialty_id")
val specialtyId: Int
)
Если в SpecialtyListViewModel написать функцию для преобразования:
fun convertSpecialtyClass(response: List <Response>): List <Specialty>{
val newList = mutableListOf<Specialty>()
response.forEach {
newList += Specialty(it.specialty[0].name.toString(), 1)
}
return newList
}
если ее вызвать фрагменте и сказать об этом адаптеру (что видимо не является правильным):
class SpecialtyListFragment : Fragment(), SpecialtyListAdaapter.Listener {
companion object {
fun newInstance() = SpecialtyListFragment()
}
private lateinit var viewModel: SpecialtyListViewModel
lateinit var specialtyListAdapter: SpecialtyListAdapter
lateinit var specialties:List<Specialty>
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
viewModel = ViewModelProvider(this).get(SpecialtyListViewModel::class.java)
val root = inflater.inflate(R.layout.specialty_list_fragment, container, false)
root.specialtyListRecyclerView.layoutManager = LinearLayoutManager(context)
specialties = viewModel.convertSpecialtyClass(viewModel.listResponse.value!!)
specialtyListAdapter = SpecialtyListAdapter(specialties, this)
specialtyListRecyclerView.adapter = specialtyListAdapter
return root
}
на выходе получаем на Runtime ошибку:
Caused by: java.lang.NullPointerException
at com.example.employee.ui.specialtylistfragment.SpecialtyListFragment.onCreateView(SpecialtyListFragment.kt:34)