From a2d33b1bdbcbecb261bc6e0a0b7b8d8990861ff0 Mon Sep 17 00:00:00 2001 From: Oleg Date: Tue, 28 Jan 2025 19:01:33 +0300 Subject: [PATCH] create homework --- .../main/java/otus/gpb/recyclerview/Chat.kt | 19 +++ .../java/otus/gpb/recyclerview/ChatAdapter.kt | 96 +++++++++++++++ .../otus/gpb/recyclerview/ChatRepository.kt | 29 +++++ .../otus/gpb/recyclerview/MainActivity.kt | 54 ++++++++ .../RecyclerViewItemDecoration.kt | 35 ++++++ app/src/main/res/drawable/action_button.xml | 12 ++ app/src/main/res/drawable/check.xml | 13 ++ app/src/main/res/drawable/divider.xml | 6 + app/src/main/res/drawable/lock.xml | 10 ++ app/src/main/res/drawable/mute.xml | 13 ++ app/src/main/res/drawable/scam.xml | 26 ++++ app/src/main/res/drawable/two_check.xml | 13 ++ app/src/main/res/drawable/verified.xml | 10 ++ app/src/main/res/layout/activity_main.xml | 10 ++ app/src/main/res/layout/chat_item.xml | 116 ++++++++++++++++++ app/src/main/res/values/colors.xml | 1 + app/src/main/res/values/themes.xml | 5 + 17 files changed, 468 insertions(+) create mode 100644 app/src/main/java/otus/gpb/recyclerview/Chat.kt create mode 100644 app/src/main/java/otus/gpb/recyclerview/ChatAdapter.kt create mode 100644 app/src/main/java/otus/gpb/recyclerview/ChatRepository.kt create mode 100644 app/src/main/java/otus/gpb/recyclerview/RecyclerViewItemDecoration.kt create mode 100644 app/src/main/res/drawable/action_button.xml create mode 100644 app/src/main/res/drawable/check.xml create mode 100644 app/src/main/res/drawable/divider.xml create mode 100644 app/src/main/res/drawable/lock.xml create mode 100644 app/src/main/res/drawable/mute.xml create mode 100644 app/src/main/res/drawable/scam.xml create mode 100644 app/src/main/res/drawable/two_check.xml create mode 100644 app/src/main/res/drawable/verified.xml create mode 100644 app/src/main/res/layout/chat_item.xml diff --git a/app/src/main/java/otus/gpb/recyclerview/Chat.kt b/app/src/main/java/otus/gpb/recyclerview/Chat.kt new file mode 100644 index 0000000..aa2ba14 --- /dev/null +++ b/app/src/main/java/otus/gpb/recyclerview/Chat.kt @@ -0,0 +1,19 @@ +package otus.gpb.recyclerview + +import androidx.annotation.DrawableRes + +data class Chat( + val id: Long, //ID + val title: String, //Название чата + val lastMessage: String, //Последнее сообщение + val lastWriter: String?, //Последний писатель сообщения + val avatar: String, //Аватар + val checkBox: Boolean, //Выделен чат или нет. + val lock: Boolean, //Приватный чат. + val scam: Boolean, //SCAM + val mute: Boolean, //Отключен звук + val verified: Boolean, //Проверенный аккаунт + val dateMessage: String, //Время сообщения + val messageCheck: Boolean, //Прочитано сообщение + val online: Boolean? = null//Онлайн. Только для пользователей. +) \ No newline at end of file diff --git a/app/src/main/java/otus/gpb/recyclerview/ChatAdapter.kt b/app/src/main/java/otus/gpb/recyclerview/ChatAdapter.kt new file mode 100644 index 0000000..b4c4071 --- /dev/null +++ b/app/src/main/java/otus/gpb/recyclerview/ChatAdapter.kt @@ -0,0 +1,96 @@ +package otus.gpb.recyclerview + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.appcompat.content.res.AppCompatResources +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView +import otus.gpb.recyclerview.ChatRepository.Companion.listChat + +class ChatAdapter : ListAdapter(ChatDiffCallback()) { + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChatItemViewHolder { + val view = LayoutInflater + .from(parent.context) + .inflate(R.layout.chat_item, parent, false) + return ChatItemViewHolder(view) + } + + override fun onBindViewHolder(holder: ChatItemViewHolder, position: Int) { + holder.bind(getItem(position)) + } + + fun removeItem(position: Int) { + listChat.removeAt(position) + } + + inner class ChatItemViewHolder(view: View) : RecyclerView.ViewHolder(view) { + + private val title = view.findViewById(R.id.title) + private val nickNameMessage = view.findViewById(R.id.nick_name_message) + private val textMessage = view.findViewById(R.id.text_message) + private val lock = view.findViewById(R.id.lock_icon_image_view) + private val scam = view.findViewById(R.id.scam_image_view) + private val mute = view.findViewById(R.id.mute_image_view) + private val verified = view.findViewById(R.id.verified_image_view) + private val dateMessageAndCheck = view.findViewById(R.id.date_message_and_check) + fun bind(chat: Chat) { + title.text = chat.title + nickNameMessage.text = chat.lastWriter + textMessage.text = chat.lastMessage + if (chat.lock) { + lock.layoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT + } else { + lock.layoutParams.width = 0 + } + + if (chat.scam) { + scam.layoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT + } else { + scam.layoutParams.width = 0 + } + + if (chat.mute) { + mute.layoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT + } else { + mute.layoutParams.width = 0 + } + + if (chat.verified) { + verified.layoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT + } else { + verified.layoutParams.width = 0 + } + + dateMessageAndCheck.text = chat.dateMessage + + if (chat.messageCheck) { + val leftDrawable = + AppCompatResources.getDrawable(itemView.context, R.drawable.check); + dateMessageAndCheck.setCompoundDrawablesWithIntrinsicBounds(leftDrawable, null, null, null); + } else{ + val leftDrawable = + AppCompatResources.getDrawable(itemView.context, R.drawable.two_check); + dateMessageAndCheck.setCompoundDrawablesWithIntrinsicBounds(leftDrawable, null, null, null); + } + + if (chat.verified) { + verified.layoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT + } else { + verified.layoutParams.width = 0 + } + } + } +} + +class ChatDiffCallback : DiffUtil.ItemCallback() { + + override fun areItemsTheSame(oldItem: Chat, newItem: Chat): Boolean = + oldItem.id == newItem.id + + override fun areContentsTheSame(oldItem: Chat, newItem: Chat): Boolean = + oldItem == newItem +} \ No newline at end of file diff --git a/app/src/main/java/otus/gpb/recyclerview/ChatRepository.kt b/app/src/main/java/otus/gpb/recyclerview/ChatRepository.kt new file mode 100644 index 0000000..e58decc --- /dev/null +++ b/app/src/main/java/otus/gpb/recyclerview/ChatRepository.kt @@ -0,0 +1,29 @@ +package otus.gpb.recyclerview + +class ChatRepository { + + companion object { + var listChat = mutableListOf( + Chat(1, "Chat1", "Message1", "Writer1", "", false, false, false, false, true,"11:01", true), + Chat(2, "Chat2", "Message2", "Writer2", "", true, true, false, true, false,"11:02", false), + Chat(3, "Chat3", "Message3", "Writer3", "", false, false, false, false, false,"11:03", true), + Chat(4, "Chat4", "Message4", "Writer4", "", true, false, true, false, true,"11:04", true), + Chat(5, "Chat5", "Message5", "Writer5", "", true, true, false, false, true,"11:05", true), + Chat(6, "Chat6", "Message6", "Writer6", "", false, false, false, true, true,"11:06", false), + Chat(7, "Chat7", "Message7", "Writer7", "", true, false, false, false, false,"11:07", true), + Chat(8, "Chat8", "Message8", "Writer8", "", false, true, false, true, false,"11:08", true), + Chat(9, "Chat9", "Message9", "Writer9", "", true, false, true, false, true,"11:09", true), + Chat(10, "Chat10", "Message10", "Writer10", "", false, false, false, true, true,"11:10", true), + Chat(11, "Chat11", "Message11", "Writer11", "", false, false, false, false, true,"11:11", true), + Chat(12, "Chat12", "Message12", "Writer12", "", true, true, false, true, false,"11:12", true), + Chat(13, "Chat13", "Message13", "Writer13", "", false, false, false, false, false,"11:13", true), + Chat(14, "Chat14", "Message14", "Writer14", "", true, false, true, false, true,"11:14", false), + Chat(15, "Chat15", "Message15", "Writer15", "", true, true, false, false, true,"11:15", true), + Chat(16, "Chat16", "Message16", "Writer16", "", false, false, false, true, true,"11:16", false), + Chat(17, "Chat17", "Message17", "Writer17", "", true, false, false, false, false,"11:17", true), + Chat(18, "Chat18", "Message18", "Writer18", "", false, true, false, true, false,"11:18", true), + Chat(19, "Chat19", "Message19", "Writer19", "", true, false, true, false, true,"11:19", true), + Chat(20, "Chat20", "Message20", "Writer20", "", false, false, false, true, true,"11:20", true) + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/otus/gpb/recyclerview/MainActivity.kt b/app/src/main/java/otus/gpb/recyclerview/MainActivity.kt index e2cdca7..606e565 100644 --- a/app/src/main/java/otus/gpb/recyclerview/MainActivity.kt +++ b/app/src/main/java/otus/gpb/recyclerview/MainActivity.kt @@ -2,11 +2,65 @@ package otus.gpb.recyclerview import androidx.appcompat.app.AppCompatActivity import android.os.Bundle +import android.widget.Button +import androidx.recyclerview.widget.ItemTouchHelper +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import otus.gpb.recyclerview.ChatRepository.Companion.listChat class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) + + val recyclerView = findViewById(R.id.recyclerView) + val chatAdapter = ChatAdapter() + recyclerView.layoutManager = LinearLayoutManager(this) + recyclerView.adapter = chatAdapter + recyclerView.addItemDecoration(RecyclerViewItemDecoration(this, R.drawable.divider)) + + chatAdapter.submitList(listChat) + + val button: Button = findViewById(R.id.add_button) + button.setOnClickListener { + listChat.add( + Chat( + 55, + "Chat55", + "Message55", + "Writer55", + "", + false, + false, + false, + false, + true, + "11:55", + true, + ) + ) + chatAdapter.notifyDataSetChanged() + } + + val itemTouchHelper = + ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) { + override fun onMove( + recyclerView: RecyclerView, + viewHolder: RecyclerView.ViewHolder, + target: RecyclerView.ViewHolder, + ): Boolean { + return false + } + + override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { + val position = viewHolder.adapterPosition + chatAdapter.removeItem(position) + chatAdapter.notifyDataSetChanged() + } + }) + + itemTouchHelper.attachToRecyclerView(recyclerView) } + } \ No newline at end of file diff --git a/app/src/main/java/otus/gpb/recyclerview/RecyclerViewItemDecoration.kt b/app/src/main/java/otus/gpb/recyclerview/RecyclerViewItemDecoration.kt new file mode 100644 index 0000000..d3ad47e --- /dev/null +++ b/app/src/main/java/otus/gpb/recyclerview/RecyclerViewItemDecoration.kt @@ -0,0 +1,35 @@ +package otus.gpb.recyclerview + +import android.content.Context +import android.graphics.Canvas +import android.graphics.drawable.Drawable +import androidx.core.content.ContextCompat +import androidx.recyclerview.widget.RecyclerView + +class RecyclerViewItemDecoration( + context: Context, + resId: Int +) : RecyclerView.ItemDecoration() { + + private var mDivider: Drawable = ContextCompat.getDrawable(context, resId)!! + + override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) { + super.onDraw(c, parent, state) + + val dividerLeft = 32 + + val dividerRight = parent.width - 32 + + for (i in 0 until parent.childCount) { + + val childAt = parent.getChildAt(i) + val params = childAt.layoutParams as RecyclerView.LayoutParams + + val dividerTop: Int = childAt.bottom + params.bottomMargin + val dividerBottom: Int = dividerTop + mDivider.intrinsicHeight + + mDivider.setBounds(dividerLeft, dividerTop, dividerRight, dividerBottom) + mDivider.draw(c) + } + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/action_button.xml b/app/src/main/res/drawable/action_button.xml new file mode 100644 index 0000000..642325a --- /dev/null +++ b/app/src/main/res/drawable/action_button.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/check.xml b/app/src/main/res/drawable/check.xml new file mode 100644 index 0000000..314a6bd --- /dev/null +++ b/app/src/main/res/drawable/check.xml @@ -0,0 +1,13 @@ + + + diff --git a/app/src/main/res/drawable/divider.xml b/app/src/main/res/drawable/divider.xml new file mode 100644 index 0000000..cf28ace --- /dev/null +++ b/app/src/main/res/drawable/divider.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/lock.xml b/app/src/main/res/drawable/lock.xml new file mode 100644 index 0000000..0efa151 --- /dev/null +++ b/app/src/main/res/drawable/lock.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/mute.xml b/app/src/main/res/drawable/mute.xml new file mode 100644 index 0000000..bd102cc --- /dev/null +++ b/app/src/main/res/drawable/mute.xml @@ -0,0 +1,13 @@ + + + + diff --git a/app/src/main/res/drawable/scam.xml b/app/src/main/res/drawable/scam.xml new file mode 100644 index 0000000..f6d9704 --- /dev/null +++ b/app/src/main/res/drawable/scam.xml @@ -0,0 +1,26 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/two_check.xml b/app/src/main/res/drawable/two_check.xml new file mode 100644 index 0000000..75abe9e --- /dev/null +++ b/app/src/main/res/drawable/two_check.xml @@ -0,0 +1,13 @@ + + + diff --git a/app/src/main/res/drawable/verified.xml b/app/src/main/res/drawable/verified.xml new file mode 100644 index 0000000..47c07b3 --- /dev/null +++ b/app/src/main/res/drawable/verified.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 2d026df..ab91cec 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,8 +1,10 @@ +