android - 当用户滚动时如何显示或隐藏日期文本视图就像whatsapp聊天android Kotlin
问题描述
嘿,我正在开发聊天应用程序。我完成了我的传入和传出消息如何为传入和传出的聊天消息使用不同的布局。我也试过这个How to show date in between conversation in recyclerview 或 in listview。我添加了输出我的一切看起来如何。
对话适配器.kt
class ConversationAdapter : ListAdapter<Message, RecyclerView.ViewHolder>(MESSAGE_COMPARATOR) {
companion object {
private val MESSAGE_COMPARATOR = object : DiffUtil.ItemCallback<Message>() {
override fun areItemsTheSame(oldItem: Message, newItem: Message): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: Message, newItem: Message): Boolean {
return ((oldItem.name == newItem.name) && (oldItem.text == oldItem.text)
&& (oldItem.time == newItem.time) && (oldItem.type == newItem.type))
}
}
private const val INCOMING_MESSAGE = 1
private const val OUTGOING_MESSAGE = 2
private const val TIMING = 3
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
INCOMING_MESSAGE -> {
IncomingViewHolder(
IncomingLayoutBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
)
}
OUTGOING_MESSAGE -> {
OutGoingViewHolder(
OutgoingLayoutBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
)
}
else -> {
TimingViewHolder(
TimingLayoutBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
)
}
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is IncomingViewHolder -> {
holder.bindItem(getItem(position))
}
is OutGoingViewHolder -> {
holder.bindItem(getItem(position))
}
is TimingViewHolder -> {
holder.bindItem(getItem(position))
}
}
}
override fun getItemViewType(position: Int): Int {
return when {
getItem(position).type.equals("incoming") -> {
INCOMING_MESSAGE
}
getItem(position).type.equals("outgoing") -> {
OUTGOING_MESSAGE
}
getItem(position).type.equals("added") -> {
TIMING
}
else -> {
super.getItemViewType(position)
}
}
}
inner class IncomingViewHolder(val binding: IncomingLayoutBinding) : RecyclerView.ViewHolder(binding.root) {
fun bindItem(item: Message) {
binding.incomingMessage.text = item.text
}
}
inner class OutGoingViewHolder(val binding: OutgoingLayoutBinding) : RecyclerView.ViewHolder(binding.root) {
fun bindItem(item: Message) {
binding.outGoingMessage.text = item.text
}
}
inner class TimingViewHolder(val binding: TimingLayoutBinding) : RecyclerView.ViewHolder(binding.root) {
fun bindItem(item: Message) {
binding.timing.text = item.time
}
}
}
MM.kt
data class Message(
val id: String? = null,
val text: String? = null,
val time: String? = null,
val type: String? = null,
val name: String? = null
)
MainActivity.kt
class MainActivity : BaseActivity() {
lateinit var binding: MainLayoutBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = MainLayoutBinding.inflate(layoutInflater)
setContentView(binding.root)
setupAdapter()
}
private fun setupAdapter() {
val list = listOf<Message>(
Message(id = "1", text = "avc", time = "2021-10-08T15:34:00", type = "outgoing"),
Message(id = "2", text = "dsds", time = "2021-10-08T15:36:00", type = "incoming"),
Message(id = "3", type = "added", time = "2021-10-08T00:00:00", name = "ABC"),
Message(id = "4", type = "added", time = "2021-10-07T15:50:00", name = "XYZ"),
Message(id = "5", text = "asvc", time = "2021-10-07T15:46:00", type = "outgoing"),
Message(id = "6", text = "asvc", time = "2021-10-07T15:46:00", type = "incoming"),
Message(id = "6", text = "asvc", time = "2021-10-06T12:34:00", type = "outgoing"),
Message(id = "8", text = "asvc", time = "2021-10-06T12:50:00", type = "incoming"),
Message(id = "9", type = "added", time = "2021-10-06T12:46:00", name = "DEF")
)
val adapter = ConversationAdapter()
binding.conversationRecyclerView.adapter = adapter
adapter.submitList(list)
}
}
计时布局.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:background="@color/aqua"
android:layout_height="wrap_content">
<TextView
android:id="@+id/timing"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
传入布局.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:background="@color/red"
android:layout_height="wrap_content">
<TextView
android:id="@+id/incomingMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
传出布局.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:background="@color/yellow"
android:layout_height="wrap_content">
<TextView
android:id="@+id/outGoingMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
输出
如何实现其他功能。
1.如何对我的日期进行分类以有效地显示每天对话之间的日期,因为我的列表太大了。我刚刚添加了示例
2.用户滚动聊天时如何显示日期的滚动效果,就像whatsapp有昨天,今天和其他日期格式一样。
3.在上面的列表示例中,添加了一个属性,这意味着在群聊中添加了某人。在 whatsapp XYZ 中使用群组邀请链接加入。
我正在添加 whatsapp 的屏幕截图
解决方案
即使不清楚“这在我的解决方案中不起作用”是什么意思,我也不知道问题是崩溃还是空列表还是......但是检查方法中的项目的逻辑areItemsTheSame
是areContentsTheSame
错误的:该方法areItemsTheSame
用于检查旧项目的身份是否等于新项目的身份。该方法areContentsTheSame
用于检查 2 项中的值是否相等
因此,areContentsTheSame
您必须只检查id
项目,因为其他事物是项目的值,而您所写的内容areContentsTheSame
没有意义,因为您只是在检查项目的参考。所以把它改成这样:
private val MESSAGE_COMPARATOR = object : DiffUtil.ItemCallback<MM>() {
override fun areItemsTheSame(oldItem: MM, newItem: MM): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: MM, newItem: MM): Boolean {
return ((oldItem.added == newItem.added)
&& (oldItem.addedTime == newItem.addedTime)
&& (oldItem.sentAt == newItem.sentAt)
&& (oldItem.text == newItem.text)) }
}
推荐阅读
- python - Python在类继承安全中重新创建实例
- python - 如何小写熊猫数据框上的 JSON 对象
- amp-html - 使用 amp-date-picker 计算日期差异
- javascript - isSupported' 未定义的 jquery
- java - 如何测试 gRPC(功能和集成测试)
- javascript - focusout 和 click 都触发回调
- python - KeyError:“斜体角度”
- reactjs - 如何触发一个组件的更改。从另一个组件
- c++ - 执行 memset 时出现 Seg Fault
- python - 使用 TOR 获取代理的 Python selenium 适用于 firefox,但不适用于 chrome