mirror of
https://github.com/imcarlost/Friendlists.git
synced 2026-04-10 02:46:54 -04:00
implement recycler view for userlist
This commit is contained in:
@@ -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()
|
||||||
|
}
|
||||||
@@ -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)
|
||||||
|
}
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
package com.hako.base.extensions
|
package com.hako.base.extensions
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.annotation.LayoutRes
|
import androidx.annotation.LayoutRes
|
||||||
|
|
||||||
fun ViewGroup.inflate(@LayoutRes layout: Int, attachToRoot: Boolean = false) =
|
fun ViewGroup.inflate(@LayoutRes layout: Int, attachToRoot: Boolean = false): View =
|
||||||
LayoutInflater
|
LayoutInflater
|
||||||
.from(context)
|
.from(context)
|
||||||
.inflate(layout, this, attachToRoot)
|
.inflate(layout, this, attachToRoot)
|
||||||
|
|||||||
@@ -5,16 +5,63 @@ import android.view.LayoutInflater
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.fragment.app.Fragment
|
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 com.hako.friendlist_userlist.R
|
||||||
|
import kotlinx.android.synthetic.main.fragment_userlist.*
|
||||||
|
|
||||||
class UserlistFragment : Fragment() {
|
class UserlistFragment : Fragment() {
|
||||||
|
|
||||||
|
private val chatAdapter by lazy { UserlistAdapter() }
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
|
||||||
container: ViewGroup?,
|
): View = inflater.inflate(R.layout.fragment_userlist, container, false)
|
||||||
savedInstanceState: Bundle?
|
|
||||||
): View {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
return inflater.inflate(R.layout.fragment_userlist, container, false)
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@ package com.hako.friendlist.model
|
|||||||
|
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import com.google.gson.annotations.SerializedName
|
import com.google.gson.annotations.SerializedName
|
||||||
|
import com.hako.base.room.entities.UserEntity
|
||||||
import kotlinx.android.parcel.Parcelize
|
import kotlinx.android.parcel.Parcelize
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
@@ -10,35 +11,18 @@ data class User(
|
|||||||
@SerializedName("name") val realName: String,
|
@SerializedName("name") val realName: String,
|
||||||
@SerializedName("username") val userName: String,
|
@SerializedName("username") val userName: String,
|
||||||
@SerializedName("email") val email: String,
|
@SerializedName("email") val email: String,
|
||||||
@SerializedName("amount") val balance: Address,
|
|
||||||
@SerializedName("phone") val phone: String,
|
@SerializedName("phone") val phone: String,
|
||||||
@SerializedName("website") val website: String,
|
@SerializedName("website") val website: String
|
||||||
@SerializedName("company") val company: Company
|
) : Parcelable
|
||||||
) : Parcelable {
|
|
||||||
|
|
||||||
@Parcelize
|
data class UserViewable(
|
||||||
data class Address(
|
val id: Int,
|
||||||
@SerializedName("street") val street: String,
|
val realName: String,
|
||||||
@SerializedName("suite") val realName: String,
|
val userName: String,
|
||||||
@SerializedName("city") val userName: String,
|
var isFavorite: Boolean = false
|
||||||
@SerializedName("zipcode") val email: String,
|
) {
|
||||||
@SerializedName("geo") val geoLocation: GeoLocation
|
fun User.toUserViewable() = UserViewable(this.id, this.realName, this.userName)
|
||||||
) : Parcelable {
|
|
||||||
|
|
||||||
@Parcelize
|
fun UserEntity.toUserViewable() = UserViewable(this.id, this.realName, this.userName)
|
||||||
data class GeoLocation(
|
|
||||||
@SerializedName("lat") val latitude: String,
|
|
||||||
@SerializedName("lng") val longitude: 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(" ")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,10 +3,14 @@
|
|||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical"
|
||||||
|
android:id="@+id/fragment_userlist_base">
|
||||||
|
|
||||||
<include
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
layout="@layout/item_user_card"
|
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_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|||||||
@@ -2,8 +2,12 @@
|
|||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/item_user_card_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="70dp"
|
android:layout_height="70dp"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
android:background="@drawable/bg_card"
|
android:background="@drawable/bg_card"
|
||||||
android:elevation="2dp"
|
android:elevation="2dp"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|||||||
Reference in New Issue
Block a user