Skip to content
Open
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
8 changes: 8 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ android {
kotlinOptions {
jvmTarget = '1.8'
}
buildFeatures {
viewBinding = true
}
dataBinding {
enabled = true
}
}

dependencies {
Expand All @@ -41,4 +47,6 @@ dependencies {
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
implementation 'androidx.databinding:databinding-runtime:8.10.0'
implementation 'it.xabaras.android:recyclerview-swipedecorator:1.4'
}
47 changes: 47 additions & 0 deletions app/src/main/java/otus/gpb/recyclerview/ChatAdapter.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package otus.gpb.recyclerview

import android.content.res.ColorStateList
import android.graphics.Color
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.ListAdapter
import otus.gpb.recyclerview.databinding.ChatItemBinding
import android.view.View.INVISIBLE
import android.view.View.VISIBLE
import kotlin.random.Random

class ChatAdapter: ListAdapter<ChatItem, ChatViewHolder>(ChatDiffCallback()) {

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChatViewHolder {
val binding = ChatItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return ChatViewHolder(binding)
}

override fun onBindViewHolder(holder: ChatViewHolder, position: Int) {
val chatItem = getItem(position)
val binding = holder.binding

when (chatItem.id % 5) {
0-> binding.imageAvatar.setImageResource(R.drawable.avatar_1)
1-> binding.imageAvatar.setImageResource(R.drawable.avatar_2)
2-> binding.imageAvatar.setImageResource(R.drawable.avatar_3)
3-> binding.imageAvatar.setImageResource(R.drawable.avatar_4)
4-> binding.imageAvatar.setImageResource(R.drawable.avatar_5)
else -> binding.imageAvatar.setImageResource(R.drawable.avatar_1)
}

binding.title.setText(chatItem.title)
binding.author.setText(chatItem.author)
binding.message.setText(chatItem.message)
if (chatItem.author == "...typing") binding.message.visibility = INVISIBLE
binding.verifiedIcon.visibility = if (chatItem.verifiedIcon) VISIBLE else INVISIBLE
binding.muteIcon.visibility = if (chatItem.muteIcon) VISIBLE else INVISIBLE
binding.scamPatch.visibility = if (chatItem.scamPatch) VISIBLE else INVISIBLE
binding.counter.visibility = if (chatItem.counter > 0) VISIBLE else INVISIBLE
binding.counter.text = if (binding.counter.visibility == VISIBLE) chatItem.counter.toString() else ""
if (Random.nextBoolean()) binding.counter.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#C5C9CC"))
binding.checkIcon.visibility = if (chatItem.check && !chatItem.read) VISIBLE else INVISIBLE
binding.readIcon.visibility = if (!chatItem.check && chatItem.read) VISIBLE else INVISIBLE
binding.time.setText(chatItem.time)
}
}
13 changes: 13 additions & 0 deletions app/src/main/java/otus/gpb/recyclerview/ChatDiffCallback.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package otus.gpb.recyclerview

import androidx.recyclerview.widget.DiffUtil

class ChatDiffCallback: DiffUtil.ItemCallback<ChatItem>() {
override fun areItemsTheSame(oldItem: ChatItem, newItem: ChatItem): Boolean {
return oldItem.id == newItem.id
}

override fun areContentsTheSame(oldItem: ChatItem, newItem: ChatItem): Boolean {
return oldItem == newItem
}
}
15 changes: 15 additions & 0 deletions app/src/main/java/otus/gpb/recyclerview/ChatItem.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package otus.gpb.recyclerview

data class ChatItem (
val id: Int,
val title: String,
val author: String,
val message: String,
val verifiedIcon: Boolean,
val muteIcon: Boolean,
val scamPatch: Boolean,
val counter: Int,
val check: Boolean,
val read: Boolean,
val time: String,
)
6 changes: 6 additions & 0 deletions app/src/main/java/otus/gpb/recyclerview/ChatViewHolder.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package otus.gpb.recyclerview

import androidx.recyclerview.widget.RecyclerView.ViewHolder
import otus.gpb.recyclerview.databinding.ChatItemBinding

class ChatViewHolder(val binding: ChatItemBinding): ViewHolder(binding.root)
117 changes: 116 additions & 1 deletion app/src/main/java/otus/gpb/recyclerview/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,126 @@ package otus.gpb.recyclerview

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import otus.gpb.recyclerview.databinding.ActivityMainBinding
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView
import it.xabaras.android.recyclerview.swipedecorator.RecyclerViewSwipeDecorator
import android.graphics.Canvas
import androidx.recyclerview.widget.LinearLayoutManager
import kotlin.random.Random

class MainActivity : AppCompatActivity() {
private val binding: ActivityMainBinding by lazy {
ActivityMainBinding.inflate(layoutInflater)
}
private var chatList: MutableList<ChatItem> = mutableListOf()
private lateinit var adapter: ChatAdapter
var id = 0
var previousItemsCount = 0
private var pageLoad = false

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setContentView(binding.root)
adapter = ChatAdapter()
binding.recyclerView.adapter = adapter

val itemTouchHelper = ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(
0, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT
) {
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
when(direction){
ItemTouchHelper.LEFT -> {
removeItem(position)
}
ItemTouchHelper.RIGHT -> {
removeItem(position)
}
}
}

override fun onChildDraw(
c: Canvas,
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
dX: Float,
dY: Float,
actionState: Int,
isCurrentlyActive: Boolean
) {
RecyclerViewSwipeDecorator.Builder(
c,
recyclerView,
viewHolder,
dX,
dY,
actionState,
isCurrentlyActive
).create().decorate()
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
}
})
itemTouchHelper.attachToRecyclerView(binding.recyclerView)
createItems(100)
setScrollListener()
}

private fun setScrollListener(){
binding.recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {

override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
val layoutManager = recyclerView.layoutManager as LinearLayoutManager
val itemsCount = layoutManager.itemCount
val lastVisibleItem = layoutManager.findLastCompletelyVisibleItemPosition()
if (pageLoad && itemsCount > previousItemsCount) {
pageLoad = false
previousItemsCount = itemsCount
}
if (!pageLoad && lastVisibleItem >= itemsCount - 5) {
getNextPage()
}
}
})
}


private fun getNextPage() {
pageLoad = true
createItems(100)
}

private fun removeItem(position: Int){
val item = adapter.currentList[position]
chatList.apply {
remove(item)
}
adapter.notifyItemRemoved(position)
}

private fun createItems(size: Int){
val title = arrayOf("Dima Murantsev" , "SnejUgal News","Catbird","just design", "R4IN80W", "Yes. No")
val author = arrayOf("Nikolay", "Anno", "You", "...typing"," ")
val message = arrayOf("you are welcome :)", "F", "I want pizza", "du biest mein sonnechein", "I see all :))", "That`s better")
for (i in 1..size) {
chatList.add(
ChatItem(id++,title[Random.nextInt(title.size)],author[Random.nextInt(author.size)],message[Random.nextInt(author.size)],
Random.nextBoolean(), Random.nextBoolean(), Random.nextBoolean(), Random.nextInt(100),
Random.nextBoolean(),Random.nextBoolean(),
Random.nextInt(24).toString() + ":" + (Random.nextInt(60).toString().padStart(2, '0'))
)
)
}
adapter.submitList(chatList)
adapter.notifyDataSetChanged()
}
}
Binary file added app/src/main/res/drawable/avatar_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/main/res/drawable/avatar_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/main/res/drawable/avatar_3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/main/res/drawable/avatar_4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/main/res/drawable/avatar_5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/main/res/drawable/check_icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/main/res/drawable/counter.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/main/res/drawable/mute_icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/main/res/drawable/read_icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/main/res/drawable/scam_patch.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/main/res/drawable/verified_icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 5 additions & 1 deletion app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".MainActivity">

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
android:layout_height="match_parent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/chat_item" />

</androidx.constraintlayout.widget.ConstraintLayout>
Loading