RecyclerView+ListAdapterを使用したチャットビュー(複数のViewHolder)
ドライバ環境最小sdk:23 現在のsdk:302 4579182 言語:Kotlin fastキャンパス授業では,中古取引アプリを作成し,チャットルームの実習を実現した.
教室では、チャットを送信するユーザが誰であろうと、右側でしかチャットレコードを送信しないため、機能をさらに改善するために、実際に使用しているチャットアプリケーションのようにユーザ:右側、相手:左側を実現する.
現在のユーザのIDは、 Adapterのパラメータで取得される. でカスタマイズされたViewHolderでは、パラメータとして受信されたidがバインドされたidと一致する場合、idのみが非表示になります. に一致しない場合、ConstraintLayout.LayoutParamsでビューを1つずつ調整しました. 実施後も、初期のRecyclerViewは正常に動作します.
メッセージを送ると、相手のチャット履歴のIDがいつも消えてしまう話題が発生します.
むしろ2つのXMLファイルで皆さんに見せたいときに適当に噴き出して、グーグルの力を借りました.
幸いなことにMediaではRecyclerViewのViewHolderを拡張して実現😂
以下のサイトはソースチャネルです.詳細な説明やその他のホットスポットがあれば、必ず入ってください.
Multiple-view-holderを参照
私のコードでは
onCreateView Holderは、パラメータを使用してView GroupとView Typeを表しますが、ほとんどがRecyclerViewを実現するために単一XMLを使用しているため、View Typeを使用する必要はありません.
Intを返しますので、初期化は次のようになります.
ListAdapterが提供する
onCreateViewHolderは、2つのViewHolderを返さなければなりません.
アダプターで使われていて、とても清潔できれいです👍🏻
自分の実践では、RecyclerViewをよりよく使用し、拡張性を実現する方法を理解しているようです.
やはり自分で改善事項をどんどん考えて、もっと良い方向があれば、自分でいろいろな方法を試して、だめなら、他の方法を探して成長して、大きな助けになります.
教室では、チャットを送信するユーザが誰であろうと、右側でしかチャットレコードを送信しないため、機能をさらに改善するために、実際に使用しているチャットアプリケーションのようにユーザ:右側、相手:左側を実現する.
まずやってみよう
現在のユーザのIDは、
メッセージを送ると、相手のチャット履歴のIDがいつも消えてしまう話題が発生します.
むしろ2つのXMLファイルで皆さんに見せたいときに適当に噴き出して、グーグルの力を借りました.
もう少しViewHolderを入れてもらえますか?
幸いなことにMediaではRecyclerViewのViewHolderを拡張して実現😂
以下のサイトはソースチャネルです.詳細な説明やその他のホットスポットがあれば、必ず入ってください.
Multiple-view-holderを参照
コードを導入する前に...
私のコードでは
Recyclerview.Adapter
ではなくListAdapter
ですが、ListAdapterの2番目のGenericタイプはView Holderを指定できると思います.onCreateView Holderは、パラメータを使用してView GroupとView Typeを表しますが、ほとんどがRecyclerViewを実現するために単一XMLを使用しているため、View Typeを使用する必要はありません.
1.getItemViewメソッドの作成と使用
override fun getItemViewType(position: Int): Int {
return super.getItemViewType(position)
}
これは、特定のリストのアイテムにtypeを設定するのと同じです.Intを返しますので、初期化は次のようになります.
companion object {
private const val MY_CHAT = 1
private const val OTHER_CHAT = 2
}
override fun getItemViewType(position: Int): Int {
return if (auth == currentList[position].senderId)
MY_CHAT
else OTHER_CHAT
}
auth
は、アダプタからパラメータとして受信された現在のユーザ(私)idである.ListAdapterが提供する
currentList
を使用して、ビューの位置を指定するsenderIdがauthと同じであれば、右側に描画します!そうでなければ相手の絵を左側に描きます!に表示されます.2.2つのViewHolder(私、相手)を作成
onCreateViewHolderは、2つのViewHolderを返さなければなりません.
inner class MyChatItemViewHolder(private val binding: ItemChatBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(chat: ChatItem) {
val dateFormat = SimpleDateFormat("HH:mm", Locale.getDefault())
val date = Date(chat.time)
binding.messageTextView.text = chat.message
binding.timeTextView.text = dateFormat.format(date)
}
}
inner class OtherChatItemViewHolder(private val binding: ItemOtherChatBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(chat: ChatItem) {
val dateFormat = SimpleDateFormat("HH:mm", Locale.getDefault())
val date = Date(chat.time)
binding.senderTextView.text = chat.senderId
binding.messageTextView.text = chat.message
binding.timeTextView.text = dateFormat.format(date)
}
}
bindingを練習している段階なので、ViewBindingを適用しました.アダプターで使われていて、とても清潔できれいです👍🏻
3.onCreateViewHolderでViewTypeを使う
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return if(viewType == MY_CHAT) {
ChatItemViewHolder(
ItemChatBinding.inflate(LayoutInflater.from(parent.context), parent, false))
} else {
ChatItem2ViewHolder(
ItemOtherChatBinding.inflate(LayoutInflater.from(parent.context), parent, false))
}
}
4.onBindViewHolderの作成
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if(getItemViewType(position) == MY_CHAT) {
(holder as MyChatItemViewHolder).bind(currentList[position])
} else {
(holder as OtherChatItemViewHolder).bind(currentList[position])
}
}
ViewHolderの戻り型はRecylcerView.ViewHolder
であるため、as
キーワードで変換される.特定のビュー領域を入れると、他のビュー領域は使用できません.以上のように、形状を変えることで簡単に解決できます!
c.f.)ListAdapaterのGenericタイプ
ListAdapter<ChatItem, RecyclerView.ViewHolder>(diffUtil)
振り返る
自分の実践では、RecyclerViewをよりよく使用し、拡張性を実現する方法を理解しているようです.
やはり自分で改善事項をどんどん考えて、もっと良い方向があれば、自分でいろいろな方法を試して、だめなら、他の方法を探して成長して、大きな助けになります.
完全なコード
class ChatItemAdapter(
private val auth: String
) : ListAdapter<ChatItem, RecyclerView.ViewHolder>(diffUtil) {
inner class MyChatItemViewHolder(private val binding: ItemChatBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(chat: ChatItem) {
val dateFormat = SimpleDateFormat("HH:mm", Locale.getDefault())
val date = Date(chat.time)
binding.messageTextView.text = chat.message
binding.timeTextView.text = dateFormat.format(date)
}
}
inner class OtherChatItemViewHolder(private val binding: ItemOtherChatBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(chat: ChatItem) {
val dateFormat = SimpleDateFormat("HH:mm", Locale.getDefault())
val date = Date(chat.time)
binding.senderTextView.text = chat.senderId
binding.messageTextView.text = chat.message
binding.timeTextView.text = dateFormat.format(date)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return if(viewType == MY_CHAT) {
MyChatItemViewHolder(
ItemChatBinding.inflate(LayoutInflater.from(parent.context), parent, false))
} else {
OtherChatItemViewHolder(
ItemOtherChatBinding.inflate(LayoutInflater.from(parent.context), parent, false))
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if(getItemViewType(position) == MY_CHAT) {
(holder as MyChatItemViewHolder).bind(currentList[position])
} else {
(holder as OtherChatItemViewHolder).bind(currentList[position])
}
}
override fun getItemViewType(position: Int): Int {
return if (auth == currentList[position].senderId)
MY_CHAT
else OTHER_CHAT
}
companion object {
val diffUtil = object : DiffUtil.ItemCallback<ChatItem>() {
override fun areItemsTheSame(oldItem: ChatItem, newItem: ChatItem): Boolean {
return oldItem == newItem
}
override fun areContentsTheSame(oldItem: ChatItem, newItem: ChatItem): Boolean {
return oldItem == newItem
}
}
private const val MY_CHAT = 1
private const val OTHER_CHAT = 2
}
}
実行画面
Reference
この問題について(RecyclerView+ListAdapterを使用したチャットビュー(複数のViewHolder)), 我々は、より多くの情報をここで見つけました https://velog.io/@minoflower31/RecyclerView-ListAdapter-로-채팅-뷰-구현하기-여러-개의-ViewHolderテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol