implement recycler view for userlist

This commit is contained in:
Carlos Martinez
2020-02-02 22:35:44 -03:00
parent 451d14ad95
commit 7d4432278e
8 changed files with 176 additions and 36 deletions

View File

@@ -0,0 +1,8 @@
package com.hako.base.extensions
import android.content.Context
import android.widget.Toast
fun Context.toast(message: String) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}

View File

@@ -0,0 +1,23 @@
package com.hako.base.extensions
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
fun <T> RecyclerView.Adapter<*>.autoNotify(oldList: List<T>, newList: List<T>, compare: (T, T) -> Boolean) {
val diff = DiffUtil.calculateDiff(object : DiffUtil.Callback() {
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return compare(oldList[oldItemPosition], newList[newItemPosition])
}
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return oldList[oldItemPosition] == newList[newItemPosition]
}
override fun getOldListSize() = oldList.size
override fun getNewListSize() = newList.size
})
diff.dispatchUpdatesTo(this)
}

View File

@@ -1,10 +1,11 @@
package com.hako.base.extensions
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.LayoutRes
fun ViewGroup.inflate(@LayoutRes layout: Int, attachToRoot: Boolean = false) =
fun ViewGroup.inflate(@LayoutRes layout: Int, attachToRoot: Boolean = false): View =
LayoutInflater
.from(context)
.inflate(layout, this, attachToRoot)

View File

@@ -5,16 +5,63 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import com.hako.base.extensions.toast
import com.hako.friendlist.model.UserViewable
import com.hako.friendlist.widget.UserlistAdapter
import com.hako.friendlist_userlist.R
import kotlinx.android.synthetic.main.fragment_userlist.*
class UserlistFragment : Fragment() {
private val chatAdapter by lazy { UserlistAdapter() }
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return inflater.inflate(R.layout.fragment_userlist, container, false)
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View = inflater.inflate(R.layout.fragment_userlist, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setRecycler()
}
private fun setRecycler() {
fragment_userlist_recycler_container.apply {
layoutManager = LinearLayoutManager(context)
adapter = chatAdapter.apply {
addAll(
listOf(
UserViewable(1, "Carlos Martinez", "carlitos"),
UserViewable(2, "Carlos Martinez", "carlitos"),
UserViewable(3, "Carlos Martinez", "carlitos"),
UserViewable(4, "Carlos Martinez", "carlitos"),
UserViewable(5, "Carlos Martinez", "carlitos"),
UserViewable(6, "Carlos Martinez", "carlitos"),
UserViewable(7, "Carlos Martinez", "carlitos"),
UserViewable(8, "Carlos Martinez", "carlitos"),
UserViewable(9, "Carlos Martinez", "carlitos"),
UserViewable(10, "Carlos Martinez", "carlitos"),
UserViewable(11, "Carlos Martinez", "carlitos"),
UserViewable(12, "Carlos Martinez", "carlitos"),
UserViewable(13, "Carlos Martinez", "carlitos"),
UserViewable(14, "Carlos Martinez", "carlitos"),
UserViewable(15, "Carlos Martinez", "carlitos"),
UserViewable(16, "Carlos Martinez", "carlitos"),
UserViewable(17, "Carlos Martinez", "carlitos"),
UserViewable(18, "Carlos Martinez", "carlitos"),
UserViewable(19, "Carlos Martinez", "carlitos"),
UserViewable(20, "Carlos Martinez", "carlitos")
)
)
onItemClick = {
context.toast(it.realName)
}
onFavoriteClick = {
context.toast(it.userName)
}
}
}
}
}

View File

@@ -2,6 +2,7 @@ package com.hako.friendlist.model
import android.os.Parcelable
import com.google.gson.annotations.SerializedName
import com.hako.base.room.entities.UserEntity
import kotlinx.android.parcel.Parcelize
@Parcelize
@@ -10,35 +11,18 @@ data class User(
@SerializedName("name") val realName: String,
@SerializedName("username") val userName: String,
@SerializedName("email") val email: String,
@SerializedName("amount") val balance: Address,
@SerializedName("phone") val phone: String,
@SerializedName("website") val website: String,
@SerializedName("company") val company: Company
) : Parcelable {
@Parcelize
data class Address(
@SerializedName("street") val street: String,
@SerializedName("suite") val realName: String,
@SerializedName("city") val userName: String,
@SerializedName("zipcode") val email: String,
@SerializedName("geo") val geoLocation: GeoLocation
) : Parcelable {
@Parcelize
data class GeoLocation(
@SerializedName("lat") val latitude: String,
@SerializedName("lng") val longitude: String
@SerializedName("website") val website: String
) : Parcelable
}
@Parcelize
data class Company(
@SerializedName("name") val name: String,
@SerializedName("catchPhrase") val catchPhrase: String,
@SerializedName("bs") val keywords: String
) : Parcelable {
fun getKeywordList() = keywords.split(" ")
}
data class UserViewable(
val id: Int,
val realName: String,
val userName: String,
var isFavorite: Boolean = false
) {
fun User.toUserViewable() = UserViewable(this.id, this.realName, this.userName)
fun UserEntity.toUserViewable() = UserViewable(this.id, this.realName, this.userName)
}

View File

@@ -0,0 +1,69 @@
package com.hako.friendlist.widget
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.hako.base.extensions.autoNotify
import com.hako.friendlist.model.UserViewable
import com.hako.friendlist_userlist.R
import kotlinx.android.synthetic.main.item_user_card.view.*
import kotlin.properties.Delegates
class UserlistAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private var items by Delegates.observable(emptyList<UserViewable>()) { _, oldList, newList ->
autoNotify(oldList, newList) { old, new -> old.id == new.id }
notifyDataSetChanged()
}
var onItemClick: (UserViewable) -> Unit = { }
var onFavoriteClick: (UserViewable) -> Unit = { }
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder =
UserViewHolder(
LayoutInflater
.from(parent.context)
.inflate(R.layout.item_user_card, parent, false),
onItemClick,
onFavoriteClick
)
fun getItem(position: Int) = items[position]
fun addAll(list: List<UserViewable>) {
items = list
}
override fun getItemCount() = items.size
override fun onBindViewHolder(viewholder: RecyclerView.ViewHolder, position: Int) =
when (viewholder) {
is UserViewHolder -> viewholder.bind(items[position])
else -> throw NoWhenBranchMatchedException("Undefined viewholder")
}
}
class UserViewHolder(private val view: View,
private val onItemClick: (UserViewable) -> Unit,
private val onFavoriteClick: (UserViewable) -> Unit) :
RecyclerView.ViewHolder(view) {
fun bind(user: UserViewable) = with(view) {
item_user_card_real_name.text = user.realName
item_user_card_user_name.text = user.userName
item_user_card_container.setOnClickListener {
onItemClick(user)
}
item_user_card_like_button.setOnClickListener {
onFavoriteClick(user)
}
}
private fun setFavorite(status: Boolean) {
when (status) {
true -> view.item_user_card_like_button.like()
false -> view.item_user_card_like_button.dislike()
}
}
}

View File

@@ -3,10 +3,14 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
android:orientation="vertical"
android:id="@+id/fragment_userlist_base">
<include
layout="@layout/item_user_card"
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/fragment_userlist_recycler_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

View File

@@ -2,8 +2,12 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/item_user_card_container"
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:background="@drawable/bg_card"
android:elevation="2dp"
android:orientation="vertical">