Skip to content
Open

Done #48

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ plugins {
}

android {
compileSdk 34
compileSdk 35
namespace "otus.gpb.recyclerview"

defaultConfig {
Expand All @@ -27,18 +27,23 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildFeatures
{
viewBinding = true
}
kotlinOptions {
jvmTarget = '1.8'
}
}

dependencies {

implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.5.1'
implementation 'com.google.android.material:material:1.7.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.core:core-ktx:1.16.0'
implementation 'androidx.appcompat:appcompat:1.7.0'
implementation 'com.google.android.material:material:1.12.0'
implementation 'androidx.constraintlayout:constraintlayout:2.2.1'
implementation 'com.github.bumptech.glide:glide:4.16.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation 'androidx.test.ext:junit:1.2.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
}
2 changes: 2 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<uses-permission android:name="android.permission.INTERNET" />

<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
Expand Down
156 changes: 154 additions & 2 deletions app/src/main/java/otus/gpb/recyclerview/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,164 @@
package otus.gpb.recyclerview

import android.annotation.SuppressLint
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.core.content.res.ResourcesCompat
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import otus.gpb.recyclerview.data.ChatItem
import otus.gpb.recyclerview.data.GroupChat
import otus.gpb.recyclerview.data.PersonChat
import otus.gpb.recyclerview.data.groupChatList
import otus.gpb.recyclerview.data.personChatList
import otus.gpb.recyclerview.databinding.ActivityMainBinding
import otus.gpb.recyclerview.ui.ChatAdapter
import otus.gpb.recyclerview.ui.CustomDecorator
import kotlin.random.Random
import androidx.recyclerview.widget.RecyclerView.OnScrollListener
import otus.gpb.recyclerview.ui.ItemTouchHelperCallback


class MainActivity : AppCompatActivity() {

private var chatItems: List<ChatItem> = emptyList()

private lateinit var binding: ActivityMainBinding
private lateinit var adapter: ChatAdapter

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)

binding.recyclerView.addItemDecoration(CustomDecorator(this).apply {
setColor(R.color.color_chat_divider_light)
setOffset(R.integer.dividerOffset)
})

binding.recyclerView.layoutManager = LinearLayoutManager(this)
adapter = ChatAdapter()

binding.recyclerView.adapter = adapter

chatItems = generateList()
adapter.submitList(chatItems)

binding.recyclerView.addOnScrollListener(object : OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)

val layoutManager = recyclerView.layoutManager as LinearLayoutManager
val totalItemCount = layoutManager.itemCount
val lastVisible = layoutManager.findLastVisibleItemPosition()

if (lastVisible > totalItemCount - 4) {
chatItems += generateList(chatItems.size)
adapter.submitList(chatItems)
}
}
})

val itemTouchCallback = ItemTouchHelperCallback(::getChatItems,::setChatItems).apply {
setSwipeEdgeParams(
resources.getInteger(R.integer.swipeEdgeCornerRadius),
resources.getColor(R.color.color_primary_light),
resources.getColor(R.color.color_chat_background_on_swipe_light)
)
ResourcesCompat.getDrawable(resources, R.drawable.icon_archive, theme)
?.let { setArchIcon(it, 20, 20, 20,
resources.getString(R.string.arch_icon_text)) }
}
ItemTouchHelper(itemTouchCallback).attachToRecyclerView(binding.recyclerView)
}
}

private fun getChatItems() = chatItems
private fun setChatItems(list: List<ChatItem>) {
chatItems = list
adapter.submitList(list)
}

private fun getRandomBool() = Random.nextInt(0, 2) > 0

@SuppressLint("DefaultLocale")
private fun getRandomTime() : String {
val hour = Random.nextInt(0, 24)
val min = Random.nextInt(0, 60)
return String.format("%d:%02d", hour, min)
}

private fun randomizeGroupChat(item: GroupChat, offset: Int) : GroupChat {
return GroupChat(
id = item.id + offset,
groupName = item.groupName,
lastAuthor = item.lastAuthor,
lastMessage = item.lastMessage,
avatarUrl = item.avatarUrl,
messagePreviewUrl = item.messagePreviewUrl,
voip = getRandomBool(),
verified = getRandomBool(),
muted = getRandomBool(),
time = getRandomTime(),
checked = getRandomBool(),
read = getRandomBool(),
mentioned = getRandomBool(),
pinned = getRandomBool(),
counter = if (Random.nextInt(0, 5) > 0) 0 else {
Random.nextInt(1, 199)
}
)
}

private fun randomizePersonChat(item: PersonChat, offset: Int) : PersonChat {
return PersonChat(
id = item.id + offset,
personName = item.personName,
lastMessage = item.lastMessage,
avatarUrl = item.avatarUrl,
messagePreviewUrl = item.messagePreviewUrl,
checkbox = getRandomBool(),
online = getRandomBool(),
locked = getRandomBool(),
scam = if (Random.nextInt(0, 5) > 0) false else getRandomBool(),
verified = getRandomBool(),
muted = getRandomBool(),
time = getRandomTime(),
checked = getRandomBool(),
read = getRandomBool(),
mentioned = getRandomBool(),
pinned = getRandomBool(),
counter = if (Random.nextInt(0, 5) > 0) 0 else {
Random.nextInt(1, 19)
}
)
}

private fun generateList(startId: Int = 0) : List<ChatItem> {
if (startId == 0) {
return listOf(
personChatList[0],
groupChatList[0],
personChatList[1],
groupChatList[1],
groupChatList[2],
personChatList[2],
groupChatList[3],
personChatList[3]
)
}
else {
return listOf(
randomizePersonChat(personChatList[0], startId),
randomizeGroupChat(groupChatList[0], startId),
randomizePersonChat(personChatList[1], startId),
randomizeGroupChat(groupChatList[1], startId),
randomizeGroupChat(groupChatList[2], startId),
randomizePersonChat(personChatList[2], startId),
randomizeGroupChat(groupChatList[3], startId),
randomizePersonChat(personChatList[3], startId)
)
}
}
}

5 changes: 5 additions & 0 deletions app/src/main/java/otus/gpb/recyclerview/data/ChatItem.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package otus.gpb.recyclerview.data

interface ChatItem {
val id: Int
}
90 changes: 90 additions & 0 deletions app/src/main/java/otus/gpb/recyclerview/data/GroupChat.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package otus.gpb.recyclerview.data

data class GroupChat (
override var id: Int,
val groupName: String,
val lastAuthor: String,
val lastMessage: String,
val avatarUrl: String,
val messagePreviewUrl: String,
var voip: Boolean,
var verified: Boolean,
var muted: Boolean,
val time: String,
var checked: Boolean,
var read: Boolean,
var mentioned: Boolean,
var pinned: Boolean,
var counter: Int
) : ChatItem

val groupChatList = listOf(
GroupChat(
id = 1,
groupName = "SnejUgal News",
lastAuthor = "Nikolay",
lastMessage = "F",
avatarUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/6/64/Fishfinger_classic_fried_2.jpg/2560px-Fishfinger_classic_fried_2.jpg",
messagePreviewUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/9/95/Moscow_%288351271825%29.jpg/500px-Moscow_%288351271825%29.jpg",
voip = true,
verified = false,
muted = true,
time = "11:38",
checked = false,
read = false,
mentioned = true,
pinned = true,
counter = 0
),
GroupChat(
id = 2,
groupName = "Unknown",
lastAuthor = "",
lastMessage = "!Don't swipe me!",
avatarUrl = "",
messagePreviewUrl = "",
voip = true,
verified = false,
muted = true,
time = "11:38",
checked = false,
read = true,
mentioned = true,
pinned = false,
counter = 0
),
GroupChat(
id = 3,
groupName = "just design",
lastAuthor = "You",
lastMessage = "I want pizza",
avatarUrl = "",
messagePreviewUrl = "",
voip = false,
verified = false,
muted = true,
time = "11:38",
checked = true,
read = false,
mentioned = false,
pinned = false,
counter = 0
),
GroupChat(
id = 4,
groupName = "Yes. No",
lastAuthor = "Anno",
lastMessage = "I see all :))",
avatarUrl = "",
messagePreviewUrl = "",
voip = false,
verified = true,
muted = false,
time = "11:38",
checked = true,
read = false,
mentioned = false,
pinned = false,
counter = 50
)
)
Loading