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..5f557cd --- /dev/null +++ b/app/src/main/java/otus/gpb/recyclerview/Chat.kt @@ -0,0 +1,10 @@ +package otus.gpb.recyclerview + +data class Chat( + val id: Int, + val title: String, + val author: String, + val message: String, + val time: String, + val icon: Int +) diff --git a/app/src/main/java/otus/gpb/recyclerview/DataSource.kt b/app/src/main/java/otus/gpb/recyclerview/DataSource.kt new file mode 100644 index 0000000..e403ecb --- /dev/null +++ b/app/src/main/java/otus/gpb/recyclerview/DataSource.kt @@ -0,0 +1,88 @@ +package otus.gpb.recyclerview + +class DataSource { + private val messagesList = listOf( + Chat( + id = 1, + title = "Title1", + author = "User1", + message = "Message1", + time = "12:00", + icon = R.drawable.cat + ), + Chat( + id = 2, + title = "Title2", + author = "User2", + message = "Message2", + time = "13:05", + icon = R.drawable.dog + ), + Chat( + id = 3, + title = "Title3", + author = "User3", + message = "Message3", + time = "9:13", + icon = R.drawable.fox + ), + Chat( + id = 4, + title = "Title4", + author = "User4", + message = "Message4", + time = "4:17", + icon = R.drawable.giraffe + ), + Chat( + id = 5, + title = "Title5", + author = "User5", + message = "Message5", + time = "10:00", + icon = R.drawable.koala + ), + Chat( + id = 6, + title = "Title6", + author = "User6", + message = "Message6", + time = "10:35", + icon = R.drawable.lion + ), + Chat( + id = 7, + title = "Title7", + author = "User7", + message = "Message7", + time = "15:16", + icon = R.drawable.owl + ), + Chat( + id = 8, + title = "Title8", + author = "User8", + message = "Message8", + time = "16:22", + icon = R.drawable.panda + ), + Chat( + id = 9, + title = "Title9", + author = "User9", + message = "Message9", + time = "21:18", + icon = R.drawable.rabbit + ), + Chat( + id = 10, + title = "Title10", + author = "User10", + message = "Message10", + time = "22:45", + icon = R.drawable.wolf + ) + ) + + fun getMessages(): List = messagesList +} \ No newline at end of file diff --git a/app/src/main/java/otus/gpb/recyclerview/ItemTouchHelperCallback.kt b/app/src/main/java/otus/gpb/recyclerview/ItemTouchHelperCallback.kt new file mode 100644 index 0000000..6d2ec1e --- /dev/null +++ b/app/src/main/java/otus/gpb/recyclerview/ItemTouchHelperCallback.kt @@ -0,0 +1,31 @@ +package otus.gpb.recyclerview + +import androidx.recyclerview.widget.ItemTouchHelper +import androidx.recyclerview.widget.RecyclerView + +class ItemTouchHelperCallback(private val listener: MessagesAdapterListener) : ItemTouchHelper.Callback() { + override fun getMovementFlags( + recyclerView: RecyclerView, + viewHolder: RecyclerView.ViewHolder + ): Int { + return makeMovementFlags( + 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 + ) { + listener.onItemSwipe(viewHolder.adapterPosition) + } +} \ 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..b944378 100644 --- a/app/src/main/java/otus/gpb/recyclerview/MainActivity.kt +++ b/app/src/main/java/otus/gpb/recyclerview/MainActivity.kt @@ -2,11 +2,58 @@ package otus.gpb.recyclerview import androidx.appcompat.app.AppCompatActivity import android.os.Bundle +import androidx.recyclerview.widget.DividerItemDecoration +import androidx.recyclerview.widget.ItemTouchHelper +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView -class MainActivity : AppCompatActivity() { +class MainActivity : AppCompatActivity(), MessagesAdapterListener { + + private lateinit var recycleView: RecyclerView + private lateinit var layoutManager: LinearLayoutManager + + private val messagesAdapter by lazy { MessagesAdapter() } + private val messagesListDataSource = DataSource().getMessages() + + private val messagesList = mutableListOf() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) + + recycleView = findViewById(R.id.recyclerView) + layoutManager = LinearLayoutManager(this) + recycleView.layoutManager = layoutManager + recycleView.addItemDecoration(DividerItemDecoration(this, DividerItemDecoration.VERTICAL)) + ItemTouchHelper(ItemTouchHelperCallback(this)).attachToRecyclerView(recycleView) + + messagesList.addAll(messagesListDataSource) + + updateRecyclerView(messagesList) + + val scrollListener = ScrollListener(layoutManager) { + loadMoreMessages() + } + recycleView.addOnScrollListener(scrollListener) + scrollListener.onLoadFinished() + } + + override fun onItemSwipe(position: Int) { + val newList = messagesList.toMutableList() + newList.removeAt(position) + messagesList.clear() + messagesList.addAll(newList) + + updateRecyclerView(messagesList) + } + + private fun updateRecyclerView(messagesList: List) { + messagesAdapter.submitList(messagesList) + recycleView.adapter = messagesAdapter + } + + private fun loadMoreMessages() { + messagesList.addAll(messagesListDataSource) + updateRecyclerView(messagesList) } } \ No newline at end of file diff --git a/app/src/main/java/otus/gpb/recyclerview/MessageViewHolder.kt b/app/src/main/java/otus/gpb/recyclerview/MessageViewHolder.kt new file mode 100644 index 0000000..644cfaa --- /dev/null +++ b/app/src/main/java/otus/gpb/recyclerview/MessageViewHolder.kt @@ -0,0 +1,26 @@ +package otus.gpb.recyclerview + +import android.view.View +import android.widget.ImageView +import android.widget.TextView +import androidx.core.content.res.ResourcesCompat +import androidx.recyclerview.widget.RecyclerView + +class MessageViewHolder(val view: View) : RecyclerView.ViewHolder(view) { + private val title: TextView by lazy { view.findViewById(R.id.title) } + private val author: TextView by lazy { view.findViewById(R.id.author) } + private val message: TextView by lazy { view.findViewById(R.id.message) } + private val time: TextView by lazy { view.findViewById(R.id.time) } + private val icon: ImageView by lazy { view.findViewById(R.id.icon) } + + fun bind(chat: Chat) { + val drawableImage = ResourcesCompat + .getDrawable(view.resources, chat.icon, null) + icon.setImageDrawable(drawableImage) + + title.text = chat.title + author.text = chat.author + message.text = chat.message + time.text = chat.time + } +} \ No newline at end of file diff --git a/app/src/main/java/otus/gpb/recyclerview/MessagesAdapter.kt b/app/src/main/java/otus/gpb/recyclerview/MessagesAdapter.kt new file mode 100644 index 0000000..9e21478 --- /dev/null +++ b/app/src/main/java/otus/gpb/recyclerview/MessagesAdapter.kt @@ -0,0 +1,25 @@ +package otus.gpb.recyclerview + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.ListAdapter + +class MessagesAdapter() : + ListAdapter(MessagesDiffCallback()) { + override fun onCreateViewHolder( + parent: ViewGroup, + viewType: Int + ): MessageViewHolder { + val view = LayoutInflater + .from(parent.context) + .inflate(R.layout.chat_item, parent, false) + return MessageViewHolder(view) + } + + override fun onBindViewHolder( + holder: MessageViewHolder, + position: Int + ) { + holder.bind(getItem(position)) + } +} \ No newline at end of file diff --git a/app/src/main/java/otus/gpb/recyclerview/MessagesAdapterListener.kt b/app/src/main/java/otus/gpb/recyclerview/MessagesAdapterListener.kt new file mode 100644 index 0000000..5146a2f --- /dev/null +++ b/app/src/main/java/otus/gpb/recyclerview/MessagesAdapterListener.kt @@ -0,0 +1,5 @@ +package otus.gpb.recyclerview + +interface MessagesAdapterListener { + fun onItemSwipe(position: Int) +} \ No newline at end of file diff --git a/app/src/main/java/otus/gpb/recyclerview/MessagesDiffCallback.kt b/app/src/main/java/otus/gpb/recyclerview/MessagesDiffCallback.kt new file mode 100644 index 0000000..a75ff8b --- /dev/null +++ b/app/src/main/java/otus/gpb/recyclerview/MessagesDiffCallback.kt @@ -0,0 +1,19 @@ +package otus.gpb.recyclerview + +import androidx.recyclerview.widget.DiffUtil + +class MessagesDiffCallback: DiffUtil.ItemCallback() { + override fun areItemsTheSame( + oldItem: Chat, + newItem: Chat + ): Boolean { + return oldItem == newItem + } + + override fun areContentsTheSame( + oldItem: Chat, + newItem: Chat + ): Boolean { + return oldItem.id == newItem.id + } +} \ No newline at end of file diff --git a/app/src/main/java/otus/gpb/recyclerview/ScrollListener.kt b/app/src/main/java/otus/gpb/recyclerview/ScrollListener.kt new file mode 100644 index 0000000..ad6f09a --- /dev/null +++ b/app/src/main/java/otus/gpb/recyclerview/ScrollListener.kt @@ -0,0 +1,30 @@ +package otus.gpb.recyclerview + +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView + +class ScrollListener( + private val layoutManager: LinearLayoutManager, + private val loadMore: () -> Unit +) : RecyclerView.OnScrollListener() { + + private var isLoading = false + + override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { + if (dy <= 0) return + + val totalItemCount = layoutManager.itemCount + val lastVisibleItem = layoutManager.findLastVisibleItemPosition() + + val isAtEnd = lastVisibleItem >= totalItemCount - 3 + + if (!isLoading && isAtEnd) { + isLoading = true + loadMore() + } + } + + fun onLoadFinished() { + isLoading = false + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/cat.png b/app/src/main/res/drawable/cat.png new file mode 100644 index 0000000..6378c9a Binary files /dev/null and b/app/src/main/res/drawable/cat.png differ diff --git a/app/src/main/res/drawable/dog.png b/app/src/main/res/drawable/dog.png new file mode 100644 index 0000000..d223de5 Binary files /dev/null and b/app/src/main/res/drawable/dog.png differ diff --git a/app/src/main/res/drawable/fox.png b/app/src/main/res/drawable/fox.png new file mode 100644 index 0000000..d34ab8f Binary files /dev/null and b/app/src/main/res/drawable/fox.png differ diff --git a/app/src/main/res/drawable/giraffe.png b/app/src/main/res/drawable/giraffe.png new file mode 100644 index 0000000..a958314 Binary files /dev/null and b/app/src/main/res/drawable/giraffe.png differ diff --git a/app/src/main/res/drawable/koala.png b/app/src/main/res/drawable/koala.png new file mode 100644 index 0000000..bd13083 Binary files /dev/null and b/app/src/main/res/drawable/koala.png differ diff --git a/app/src/main/res/drawable/lion.png b/app/src/main/res/drawable/lion.png new file mode 100644 index 0000000..6e11824 Binary files /dev/null and b/app/src/main/res/drawable/lion.png differ diff --git a/app/src/main/res/drawable/owl.png b/app/src/main/res/drawable/owl.png new file mode 100644 index 0000000..c0e5d5f Binary files /dev/null and b/app/src/main/res/drawable/owl.png differ diff --git a/app/src/main/res/drawable/panda.png b/app/src/main/res/drawable/panda.png new file mode 100644 index 0000000..6ed4416 Binary files /dev/null and b/app/src/main/res/drawable/panda.png differ diff --git a/app/src/main/res/drawable/rabbit.png b/app/src/main/res/drawable/rabbit.png new file mode 100644 index 0000000..d900afa Binary files /dev/null and b/app/src/main/res/drawable/rabbit.png differ diff --git a/app/src/main/res/drawable/wolf.png b/app/src/main/res/drawable/wolf.png new file mode 100644 index 0000000..7c3234c Binary files /dev/null and b/app/src/main/res/drawable/wolf.png differ diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 2d026df..3459e83 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -3,6 +3,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" + xmlns:app="http://schemas.android.com/apk/res-auto" tools:context=".MainActivity"> + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index f8c6127..87d3fd3 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -7,4 +7,7 @@ #FF018786 #FF000000 #FFFFFFFF + #517DA2 + #416482 + #66A9E0 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3d78b1f..0b263a3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,3 +1,4 @@ - RecyclerView + Telegram + \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 2187cf1..c2f2272 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -2,8 +2,8 @@