嘿,我正在创建一个类型为INCOMING的列表即将离任,和通过enum类。我的数据类是通过api调用填充的,并根据列表中的api调用填充。我想修改添加时间enum值,每当日期结束当前一个。
fun main() {
val list = mutableListOf(
Conversation(ConversationType.INCOMING.value, Sender(1, "2021/10/12")),
Conversation(ConversationType.INCOMING.value, Sender(2, "2021/10/12")),
Conversation(ConversationType.OUTGOING.value, Sender(3, "2021/10/11")),
Conversation(ConversationType.OUTGOING.value, Sender(4, "2021/10/11")),
Conversation(ConversationType.OUTGOING.value, Sender(5, "2021/10/11")),
Conversation(ConversationType.OUTGOING.value, Sender(6, "2021/10/09")),
Conversation(ConversationType.INCOMING.value, Sender(7, "2021/10/09")),
Conversation(ConversationType.INCOMING.value, Sender(8, "2021/10/09")),
Conversation(ConversationType.INCOMING.value, Sender(9, "2021/10/09")),
Conversation(ConversationType.OUTGOING.value, Sender(10, "2021/10/08")),
Conversation(ConversationType.OUTGOING.value, Sender(11, "2021/10/07"))
)
}
Enum类
enum class ConversationType(val value: Int) {
INCOMING(1),
TIME(0),
OUTGOING(2);
}
data class Conversation(
val type: Int? = null,
val sender: Sender
)
data class Sender(
val id: Int? = null,
val date: String? = null
)
我需要这样的输出
Conversation(type=1, sender=Sender(id=1, date=2021/10/12))
Conversation(type=1, sender=Sender(id=2, date=2021/10/12))
Conversation(type=0, sender=Sender(id=null, date=2021/10/12))
Conversation(type=2, sender=Sender(id=3, date=2021/10/11))
Conversation(type=2, sender=Sender(id=4, date=2021/10/11))
Conversation(type=2, sender=Sender(id=5, date=2021/10/11))
Conversation(type=0, sender=Sender(id=null, date=2021/10/11))
Conversation(type=2, sender=Sender(id=6, date=2021/10/09))
Conversation(type=1, sender=Sender(id=7, date=2021/10/09))
Conversation(type=1, sender=Sender(id=8, date=2021/10/09))
Conversation(type=1, sender=Sender(id=9, date=2021/10/09))
Conversation(type=0, sender=Sender(id=null, date=2021/10/09))
Conversation(type=2, sender=Sender(id=10, date=2021/10/08))
Conversation(type=0, sender=Sender(id=null, date=2021/10/08))
Conversation(type=2, sender=Sender(id=11, date=2021/10/07))
Conversation(type=0, sender=Sender(id=null, date=2021/10/07))
我知道你想要什么,你需要这样的东西:
var previousDate: String? = null
var i = -1
while (i < list.size) {
i++
val currentDate = list[i].date
previousDate?.let {
if (currentDate != previousDate) {
list.add(i + 1, Conversation(ConversationType.TIME.value, Sender(null, it)))
}
}
previousDate = currentDate
}
其他人已经提供了基于手动迭代索引的解决方案。另一种更容易理解的方法是使用可变迭代器。结果代码几乎与您最初的尝试相同:
val iter = list.listIterator()
var previousDate = iter.next().sender?.date
iter.forEach { conversation ->
val date = conversation.sender?.date
if (date != previousDate) {
iter.add(Conversation(...))
previousDate = date
}
}
与可变的迭代器我们可以在需要的地方添加一个项目在迭代。我们不需要手动管理索引。
如果列表为空,该解决方案将抛出异常,因此我们可能应该为这种情况添加一个检查。您还应该考虑sender
或date
是null
的情况。在这种情况下,目前提供的所有解决方案的行为都是奇怪的,并且您没有指定期望的行为。
由于您希望在迭代列表时向列表添加项,因此需要迭代索引,以便可以随时插入项。由于列表在不断增长,您需要使用while循环而不是原始索引的for循环。
var previousDate: String? = null
var i = 0
while (i < list.size) {
val newDate = list[i].date
if (newDate != previousDate && previousDate != null) {
list.add(i++, Conversation(ConversationType.TIME.value, Sender(null, previousDate)))
}
previousDate = newDate
i++
}
为了解释我关于简化使用密封接口的建议,下面是我将如何重新设计的。我将把你上面的类替换为:
sealed interface Conversation {
val date: String
}
sealed interface ConversationMessage: Conversation {
val senderId: Int
}
data class IncomingConversation(
override val date: String,
override val senderId: Int
): ConversationMessage
data class OutgoingConversation(
override val date: String,
override val senderId: Int
): ConversationMessage
data class TimeStampConversation(override val date: String): Conversation
那么你就不必担心任何东西都是空的,你不必解包枚举值,并且所有的构造函数都更容易使用。您可以使用when
语句和is
检查来确定在您的RecyclerView中使用哪个视图holder。