Добавить данные в Recyclerview в Kotlin Android

Я использую Volley для чтения JSON API. Все работает над этим. Когда я смотрю на время прибытия, которое я получаю от API, меняются, что я ожидаю.

Выход JSON

10-24 08:34:17.831 4671-4671/org.sherman.tony.nexttrain I/System.out: ARRIVAL TIME = 1508849280 10-24 08:34:17.831 4671-4671/org.sherman.tony.nexttrain I/System.out: ARRIVAL TIME = 1508850180 10-24 08:34:17.831 4671-4671/org.sherman.tony.nexttrain I/System.out: ARRIVAL TIME = 1508850600 10-24 08:34:17.831 4671-4671/org.sherman.tony.nexttrain I/System.out: ARRIVAL TIME = 1508848920 10-24 08:34:17.832 4671-4671/org.sherman.tony.nexttrain I/System.out: ARRIVAL TIME = 1508851500 10-24 08:34:17.832 4671-4671/org.sherman.tony.nexttrain I/System.out: ARRIVAL TIME = 1508851980 10-24 08:34:17.832 4671-4671/org.sherman.tony.nexttrain I/System.out: ARRIVAL TIME = 1508849340 10-24 08:34:17.832 4671-4671/org.sherman.tony.nexttrain I/System.out: ARRIVAL TIME = 1508850000 10-24 08:34:17.832 4671-4671/org.sherman.tony.nexttrain I/System.out: ARRIVAL TIME = 1508849760 10-24 08:34:17.832 4671-4671/org.sherman.tony.nexttrain I/System.out: ARRIVAL TIME = 1508849340 10-24 08:34:17.832 4671-4671/org.sherman.tony.nexttrain I/System.out: ARRIVAL TIME = 1508848680 10-24 08:34:17.832 4671-4671/org.sherman.tony.nexttrain I/System.out: ARRIVAL TIME = 1508850000 10-24 08:34:17.832 4671-4671/org.sherman.tony.nexttrain I/System.out: ARRIVAL TIME = 1508851980 

Мой код добавляет правильное количество элементов в ArrayList, но когда я просматриваю данные в ресайклере, это несколько вхождений последнего захваченного элемента:

 10-24 08:34:17.929 4671-4671/org.sherman.tony.nexttrain I/System.out: ARRIVAL TIME ===> 1508851980 10-24 08:34:17.932 4671-4671/org.sherman.tony.nexttrain I/System.out: ARRIVAL TIME ===> 1508851980 10-24 08:34:17.935 4671-4671/org.sherman.tony.nexttrain I/System.out: ARRIVAL TIME ===> 1508851980 10-24 08:34:17.940 4671-4671/org.sherman.tony.nexttrain I/System.out: ARRIVAL TIME ===> 1508851980 10-24 08:34:17.942 4671-4671/org.sherman.tony.nexttrain I/System.out: ARRIVAL TIME ===> 1508851980 10-24 08:34:17.945 4671-4671/org.sherman.tony.nexttrain I/System.out: ARRIVAL TIME ===> 1508851980 10-24 08:34:17.950 4671-4671/org.sherman.tony.nexttrain I/System.out: ARRIVAL TIME ===> 1508851980 10-24 08:34:17.954 4671-4671/org.sherman.tony.nexttrain I/System.out: ARRIVAL TIME ===> 1508851980 10-24 08:34:17.970 4671-4671/org.sherman.tony.nexttrain I/System.out: ARRIVAL TIME ===> 1508851980 

Это сердце моего кода деятельности:

 // Get a list of train schedules // listOfTrains = ArrayList<TrainStatus>() volleyRequest = Volley.newRequestQueue(this) readTrains(url,station) } fun readTrains(url:String, station: String) { var listOfTrains = ArrayList<TrainStatus>() var trainStatus = TrainStatus() println("URL ===> $url") val jsonObjectRequest = JsonObjectRequest(Request.Method.GET,url, Response.Listener { response: JSONObject -> try { val responseMode = response.getJSONArray("mode") val responseModeRouteObj = responseMode.getJSONObject(0) val responseModeRouteObjRoute = responseModeRouteObj.getJSONArray("route") for (i in 0..responseModeRouteObjRoute.length() - 1){ val responseModeRouteObjRouteRouteObj = responseModeRouteObjRoute.getJSONObject(i) val responseModeRouteObjRouteRouteObjDirection = responseModeRouteObjRouteRouteObj.getJSONArray("direction") for (j in 0.. responseModeRouteObjRouteRouteObjDirection.length() - 1){ val responseModeRouteObjRouteRouteObjDirectionDirectionObj = responseModeRouteObjRouteRouteObjDirection.getJSONObject(j) val direction = responseModeRouteObjRouteRouteObjDirectionDirectionObj.getString("direction_id") trainStatus.direction_id = direction.toInt() val tripArray = responseModeRouteObjRouteRouteObjDirectionDirectionObj.getJSONArray("trip") for (k in 0..tripArray.length() - 1){ var tripArrayObj = tripArray.getJSONObject(k) var schArrival = tripArrayObj.getString("sch_arr_dt") trainStatus.sch_arr_time = schArrival.toLong() trainStatus.station = station println("ARRIVAL TIME = ${trainStatus.sch_arr_time}") // DEBUGGING print statement listOfTrains!!.add(trainStatus) } } } trainAdapter = TrainListAdapter(listOfTrains, this) layoutManager = LinearLayoutManager(this) // Set up recycler Adapter recyclerViewID.layoutManager = layoutManager recyclerViewID.adapter = trainAdapter trainAdapter!!.notifyDataSetChanged() } catch (e: JSONException){e.printStackTrace()} }, Response.ErrorListener { error: VolleyError? -> try{ error!!.printStackTrace() }catch(e:JSONException) { e.printStackTrace() } }) //val list:ArrayList<TrainList>? = null volleyRequest!!.add(jsonObjectRequest) println("SIZE OF ARRAY ===> ${listOfTrains.size}") return //return list } 

И это мой код адаптера:

 package org.sherman.tony.nexttrain.adapters import android.content.Context import android.support.v7.widget.RecyclerView import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.TextView import org.sherman.tony.nexttrain.models.TrainStatus import org.sherman.tony.nexttrain.R import java.text.DateFormat import java.text.SimpleDateFormat import java.util.* class TrainListAdapter(var listOfTrains: ArrayList<TrainStatus>, val context: Context): RecyclerView.Adapter<TrainListAdapter.ViewHolder>() { override fun onCreateViewHolder(parent: ViewGroup?, position: Int): ViewHolder { val view = LayoutInflater.from(context) .inflate(R.layout.station_lst_item, parent, false) return ViewHolder(view) } override fun getItemCount(): Int { return listOfTrains.size } override fun onBindViewHolder(holder: ViewHolder?, position: Int) { holder!!.bindView(listOfTrains[position]) } inner class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) { var station = itemView.findViewById<TextView>(R.id.stationListTextViewID) var arrivalTime = itemView.findViewById<TextView>(R.id.timeScheduleID) fun bindView(train: TrainStatus){ var humanTime = readableTime(train.sch_arr_time!!) println("ARRIVAL TIME ===> ${train.sch_arr_time}") station.text = train.station.toString() //arrivalTime.text = humanTime arrivalTime.text = train.sch_arr_time.toString() } fun readableTime(milliSeconds: Long): String { var date = Date(milliSeconds) val dateFormat: DateFormat = SimpleDateFormat("H:mm") return dateFormat.format(date) } } } 

Как получить адаптер для добавления фактических возвращенных значений вместо нескольких копий последнего элемента.

Спасибо.

Думаю, я выяснил эту проблему. Вы создаете список TrainStatus и получаете этот список из удаленного API. Для каждого вызова вы повторяете и добавляете полученный результат. Проблема заключается в объявлении переменной trainStatus.

Вы выполняете var trainStatus = TrainStatus () вне функции readTrains, а затем на каждой итерации вы изменяете значение этой переменной и добавляете ее в список.

Вы делаете это, но вы не создаете новый экземпляр для каждого TrainStatus, который хотите добавить, поэтому каждый раз добавляете один и тот же экземпляр одного и того же объекта в свой список, просто изменяя значение в нем. Таким образом, каждый элемент списка указывает на тот же объект TrainStatus, который удерживает значение последнего элемента, полученного от вашего запроса.

Чтобы исправить пробой, просто создавайте новый экземпляр каждый раз, когда вы начинаете новую итерацию.

Поэтому измените свой код на:

 for (i in 0..responseModeRouteObjRoute.length() - 1){ val responseModeRouteObjRouteRouteObj = responseModeRouteObjRoute.getJSONObject(i) val responseModeRouteObjRouteRouteObjDirection = responseModeRouteObjRouteRouteObj.getJSONArray("direction") for (j in 0.. responseModeRouteObjRouteRouteObjDirection.length() - 1){ val responseModeRouteObjRouteRouteObjDirectionDirectionObj = responseModeRouteObjRouteRouteObjDirection.getJSONObject(j) val direction = responseModeRouteObjRouteRouteObjDirectionDirectionObj.getString("direction_id") val tripArray = responseModeRouteObjRouteRouteObjDirectionDirectionObj.getJSONArray("trip") for (k in 0..tripArray.length() - 1){ trainStatus.direction_id = TrainStatus() trainStatus.direction_id = direction.toInt() var tripArrayObj = tripArray.getJSONObject(k) var schArrival = tripArrayObj.getString("sch_arr_dt") trainStatus.sch_arr_time = schArrival.toLong() trainStatus.station = station println("ARRIVAL TIME = ${trainStatus.sch_arr_time}") // DEBUGGING print statement listOfTrains!!.add(trainStatus) } } } 

Я также предлагаю вам не создавать новый экземпляр адаптера для каждого вашего вызова, кроме как напрямую сохранить список trainstatus в адаптере