我有一个问题,当我向arraylist添加一个数据类新元素时,它总是用新元素替换当前元素。你能告诉我问题所在和解决方案吗。提前谢谢
模型
import android.os.Parcelable
import com.google.gson.annotations.SerializedName
import kotlinx.android.parcel.Parcelize
@Parcelize
data class ScheduleModel(
@field:SerializedName("user_available_id")
var userAvailableId: String? = null,
@field:SerializedName("teacher_id")
var teacherId: String? = null,
@field:SerializedName("schedule")
var schedule: ArrayList<schedule?>? = null
) : Parcelable
@Parcelize
data class schedule(
@field:SerializedName("event_id")
var eventId: String? = null,
@field:SerializedName("schedule_time")
var scheduleTime: String? = null,
@field:SerializedName("status")
var status: String? = null
) : Parcelable
我正在使用recyclerview向arraylist添加元素。元素是数据类模型。下面是流程,首先我从API获取数据,然后用recyclerview显示数据。然后在显示之后,我想获取显示数据并将其保存到数组列表中。将数据保存到arraylist后,arraylist会将数据发送到api,如下所示:
{
"user_available_id": 702,
"teacher_id" : 3207,
"schedule" : [{
"event_id" : 47533,
"schedule_time" : "2020-11-30 07:00:00",
"status" :1
},
{
"event_id" : 47532,
"schedule_time" : "2020-11-30 06:30:00",
"status" :1
}]
}
当我向arraylist添加新数据时,保存到arraylist的数据总是会用新数据覆盖当前数据。
功能
private suspend fun getMultiSlotJadwal(id: String, date: String) {
jamList.clear()
val networkConfig =
NetworkConfig().getTeacher().getTeacherScheduleAvailability(token, id, date)
if (networkConfig.isSuccessful) {
if (networkConfig.body()!!.availability!!.isEmpty()) {
binding.rvSlot.visibility = View.GONE
Handler(Looper.getMainLooper()).post {
Toast.makeText(
this,
"Jam tidak tersedia",
Toast.LENGTH_SHORT
).show()
}
} else {
for (slot in networkConfig.body()!!.availability!!) {
//convert tanggal start ke millis
val tanggalSlot = slot!!.start!!.toDate().formatTo("yyyy-MM-dd HH:mm")
val tanggalInMillis = convertToMillis(tanggalSlot)
//ambil tanggal sekarang
val myFormat = "yyyy-MM-dd HH:mm" // format tanggal
val calendar = Calendar.getInstance()
val time = calendar.time
val sdf = SimpleDateFormat(myFormat, Locale.getDefault())
val curdate = sdf.format(time) //diconvert ke tanggal local
val curDateinMillis = convertToMillis(curdate) // convert ke millis
val hasilDate = tanggalInMillis - curDateinMillis
val tanggalJam = hasilDate / 3600000 //diubah dari millis ke jam
if (tanggalJam >= 6) {
jamList.add(slot)
val sortJamList = jamList.sortedBy { jamList -> jamList.start }
binding.rvSlot.visibility = View.VISIBLE
val adapter = SlotJamMultiAdapter(sortJamList) {
teacher_id = it.teacherId.toString()
scheduleModel.userAvailableId = user_avalaible_id //model
scheduleModel.teacherId = teacher_id
scheduleItem.scheduleTime = it.start.toString()
scheduleItem.status = "1"
scheduleItem.eventId = it.id.toString()
scheduleList.add(scheduleItem) // array list
scheduleModel.schedule = scheduleList
Log.d(TAG, "getMultiSlotJadwal: $scheduleList")
itemClicked = true
changeBackgroundButtonSesi2()
}
adapter.submitList(sortJamList)
binding.rvSlot.adapter = adapter
}
}
}
} else {
Handler(Looper.getMainLooper()).post {
Toast.makeText(
this,
"Jam tidak tersedia",
Toast.LENGTH_SHORT
).show()
}
}
}
使用diffutils适配器后,编辑这里的我的适配器
class SlotJamMultiAdapter(
private var data: List<AvailabilitySlotItem>,
private val listener: (AvailabilitySlotItem) -> Unit
) : RecyclerView.Adapter<SlotJamMultiAdapter.LeagueViewHolder>() {
private lateinit var ContextAdapter: Context
class LeagueViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val tvJam = view.findViewById<TextView>(R.id.tv_slot_jam_list)
val cvSlot = view.findViewById<CardView>(R.id.cv_slot_list)
val llSlot = view.findViewById<LinearLayout>(R.id.ll_cv_slot)
fun bidnItem(
data: AvailabilitySlotItem,
listener: (AvailabilitySlotItem) -> Unit,
context: Context,
position: Int
) {
val jam = data.start!!.toDate().formatTo("HH:mm")
tvJam.text = jam
itemView.setOnClickListener {
listener(data)
}
}
private fun String.toDate(
dateFormat: String = "yyyy-MM-dd HH:mm:ss",
timeZone: TimeZone = TimeZone.getTimeZone("UTC")
): Date {
val parser = SimpleDateFormat(dateFormat, Locale.getDefault())
parser.timeZone = timeZone
return parser.parse(this)
}
private fun Date.formatTo(
dateFormat: String,
timeZone: TimeZone = TimeZone.getDefault()
): String {
val formatter = SimpleDateFormat(dateFormat, Locale.getDefault())
formatter.timeZone = timeZone
return formatter.format(this)
}
}
class slotItemDiffCallback(
var oldSlotList: List<AvailabilitySlotItem>,
var newSlotList: List<AvailabilitySlotItem>
) : DiffUtil.Callback() {
override fun getOldListSize(): Int {
return oldSlotList.size
}
override fun getNewListSize(): Int {
return newSlotList.size
}
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return (oldSlotList.get(oldItemPosition).id == newSlotList.get(newItemPosition).id)
}
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return oldSlotList.get(oldItemPosition).equals(newSlotList.get(newItemPosition))
}
}
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): SlotJamMultiAdapter.LeagueViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
ContextAdapter = parent.context
val inflatedView: View = layoutInflater.inflate(R.layout.slot_list, parent, false)
return SlotJamMultiAdapter.LeagueViewHolder(inflatedView)
}
override fun onBindViewHolder(holder: SlotJamMultiAdapter.LeagueViewHolder, position: Int) {
holder.bidnItem(data[position], listener, ContextAdapter, position)
}
override fun getItemCount(): Int = data.size
fun submitList(availabilitySlotItemList: List<AvailabilitySlotItem>) {
val oldList = data
val diffResult:DiffUtil.DiffResult=DiffUtil.calculateDiff(
slotItemDiffCallback(
oldList,availabilitySlotItemList
)
)
data = availabilitySlotItemList
diffResult.dispatchUpdatesTo(this)
}
}
因为每次使用getMultiSlotJadwal()获取列表时,您都会创建一个新的适配器实例并将其分配给回收人员视图。
binding.rvSlot.adapter = SlotJamMultiAdapter(sortJamList) { }
继续引用分配的适配器,然后当从服务器获取新列表时,将该列表提供给先前引用的适配器。
您可以搜索ListAdatper/DiffUtil。回调时,它们会代表您检查新列表中的项目是否与旧列表中的项目相同。您所要做的就是将新列表提交到下面的ListAdapter
val newList = getNewListFromServer()
myAdapter.submitList(list)
更新了
好的,对于ScheduleModel
class ScheduleModel(
val userAvailableId : String?,
val teacherId : String?,
val schedule : List<String>?
) {
class ScheduleDiffUtilCallback : DiffUtil.ItemCallback<ScheduleModel>(){
override fun areItemsTheSame(oldItem: ScheduleModel, newItem: ScheduleModel): Boolean {
return true
// set the way how to identify if the newItem is the same as the oldItem
}
override fun areContentsTheSame(oldItem: ScheduleModel, newItem: ScheduleModel): Boolean {
return true
// set the way how to identify if the newItem's contents is the same as the oldItem's contents
}
}
}
对于适配器
class SlotJamMultiAdapter : ListAdapter<ScheduleModel, SlotJamMultiAdapter.ViewHolder>(
ScheduleModel.ScheduleDiffUtilCallback()
){
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.item_schedule, parent, false)
)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = getItem(position)
holder.bind(item)
}
class ViewHolder(root : View) : RecyclerView.ViewHolder(root) {
fun bind(item : ScheduleModel) {
//bind data to view here
}
}
}
实际上不引用数据的节点在适配器类中列出自己。ListAdapter将引用它并执行更新数据所需的所有操作。
你所要做的就是,在片段或活动中
val adapter = SlotJamMultiAdapter()
rc.adapter = adapter
当你的数据发生变化时(如果你得到了新的列表)
adapter.submitList(newList)
请注意,我没有创建新的适配器实例,我正在引用连接到recyclerview的旧适配器,并且正在重用它
问题内容: 首先,对无法提供任何源代码表示歉意。我的项目很大,将所有内容链接起来都是不切实际的,而且我还无法缩小非常烦人的问题。我将尽力在这里进行解释。 我在代码的每个循环中动态创建类的新实例。在循环中会为该实例动态地提供几个属性,例如’name’。在每个循环的最后,新生成的实例将添加到另一个第3类中保存的ArrayList中。 但是,问题在于,无论出于何种原因添加新元素时,所有先前的元素都会更改
我是Java新手,使用对象的编写Java小应用程序。 我以为ArrayList对象会为将要添加到列表中的每个新元素添加新索引,而从不修改以前的元素。我的代码怎么了?
问题内容: 下面有一个for循环代码。我通过调用一个自定义显示函数发现aBook arrayList对象仅添加了最后一个类对象三次。为什么会这样呢? 这是我的LiFiAddressBook类 } 问题答案: 由于使用static关键字,每次 调用构造函数时,旧值都会被新值覆盖,并且在打印列表中的元素时,LiFiAddressBook类的对象变量将指向相同的对象。因此打印相似的对象。 需要明确的是,
给定两个排序整数数组A和B,将B合并为A作为一个排序数组。 注意:您必须修改数组A,以包含A和B的合并。不要在代码中输出任何内容。提示:C用户,请将结果malloc到一个新的数组中并返回结果。 如果A和B中初始化的元素数分别为m和n,则代码执行后数组A的结果大小应为m+n
在本例中,我的代码是: CSS: } 我有一些代码用于我希望使用的指示器,它是发光效果:
问题内容: 我对Java编程还是很陌生,我正在尝试使用以下代码来更新an的现有值: 我想打印而不是打印,但得到的结果仍然是。我要打印。我怎样才能做到这一点?谢谢。 问题答案: 使用该方法将旧值替换为新值。
当我使用System.out.println静态方法时,下面的Java程序显示ArrayList中的所有元素。但是,当我在方法中返回列表时,它只显示ArrayList中的一个元素。我希望你能给我一些指点,让我知道你做错了什么:
问题内容: 我以为链表在添加元素时应该比数组表快?我只是测试了添加,排序和搜索元素(数组列表,链表,哈希集)需要多长时间。我只是对数组列表和链接列表使用java.util类…使用每个类都可以使用的两个add(object)方法。 arraylist在填充列表中执行链表…并在列表中进行线性搜索。 这是正确的吗?我在执行中做错了吗? *_ __ _ _ __ _编辑 __ * __ __ * * 我只