在Kotlin Android中将数据添加到RecyclerView

我使用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() volleyRequest = Volley.newRequestQueue(this) readTrains(url,station) } fun readTrains(url:String, station: String) { var listOfTrains = ArrayList() 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? = 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, val context: Context): RecyclerView.Adapter() { 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(R.id.stationListTextViewID) var arrivalTime = itemView.findViewById(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获取该列表。 对于每个调用你迭代并添加给定的结果。 问题在于variablestrainStatus的声明。

你可以在函数readTrains之外做一个var trainStatus = TrainStatus(),然后在每次迭代中改变这个variables的值并把它添加到列表中。

您可以这样做,但不要为要添加的每个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的列表