From 3326608b19d8b8501a606fb0b46389a569f8209c Mon Sep 17 00:00:00 2001 From: isolino Date: Wed, 20 May 2020 09:04:36 -0300 Subject: [PATCH] refactoring RecyclerView.Adapter to ListAdapter --- .../br/com/renatoarg/ui/home/HomeFragment.kt | 12 +----- .../ui/home/adapter/UsersDiffUtilCallback.kt | 14 ++++++ .../ui/home/adapter/UsersListAdapter.kt | 43 ++++++------------- .../adapter/viewholder/ErrorViewHolder.kt | 36 ++++++++++++++++ .../adapter/viewholder/UserOkViewHolder.kt | 26 +++++------ .../adapter/viewholder/UsersViewHolder.kt | 30 +++++++++++++ app/src/main/res/layout/item_error.xml | 40 +++++++++++++++++ 7 files changed, 145 insertions(+), 56 deletions(-) create mode 100644 app/src/main/java/br/com/renatoarg/ui/home/adapter/UsersDiffUtilCallback.kt create mode 100644 app/src/main/java/br/com/renatoarg/ui/home/adapter/viewholder/ErrorViewHolder.kt create mode 100644 app/src/main/java/br/com/renatoarg/ui/home/adapter/viewholder/UsersViewHolder.kt create mode 100644 app/src/main/res/layout/item_error.xml diff --git a/app/src/main/java/br/com/renatoarg/ui/home/HomeFragment.kt b/app/src/main/java/br/com/renatoarg/ui/home/HomeFragment.kt index 407cf36..6ec4e8b 100644 --- a/app/src/main/java/br/com/renatoarg/ui/home/HomeFragment.kt +++ b/app/src/main/java/br/com/renatoarg/ui/home/HomeFragment.kt @@ -1,19 +1,16 @@ package br.com.renatoarg.ui.home -import android.content.Context import android.os.Bundle import android.view.View import android.widget.ImageView import androidx.fragment.app.Fragment import androidx.lifecycle.Observer -import androidx.navigation.fragment.FragmentNavigatorExtras import androidx.navigation.fragment.findNavController import br.com.renatoarg.R import br.com.renatoarg.model.pojo.User import br.com.renatoarg.ui.home.adapter.UsersListAdapter import br.com.renatoarg.ui.home.adapter.viewholder.UsersListInterface import kotlinx.android.synthetic.main.fragment_home.* -import kotlinx.android.synthetic.main.item_user.* import org.koin.androidx.viewmodel.ext.android.sharedViewModel import timber.log.Timber @@ -23,12 +20,7 @@ import timber.log.Timber class HomeFragment : Fragment(R.layout.fragment_home), UsersListInterface { private val viewModel: HomeViewModel by sharedViewModel() - private lateinit var usersListAdapter : UsersListAdapter - - override fun onAttach(context: Context) { - super.onAttach(context) - usersListAdapter = UsersListAdapter(context, emptyList(), this) - } + private val usersListAdapter : UsersListAdapter = UsersListAdapter(this) override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -48,7 +40,7 @@ class HomeFragment : Fragment(R.layout.fragment_home), UsersListInterface { } private fun setupForUsersLoaded(usersList: List) { - usersListAdapter.updateUsers(usersList) + usersListAdapter.submitList(usersList) } private fun setupForInit() { diff --git a/app/src/main/java/br/com/renatoarg/ui/home/adapter/UsersDiffUtilCallback.kt b/app/src/main/java/br/com/renatoarg/ui/home/adapter/UsersDiffUtilCallback.kt new file mode 100644 index 0000000..42b9bf8 --- /dev/null +++ b/app/src/main/java/br/com/renatoarg/ui/home/adapter/UsersDiffUtilCallback.kt @@ -0,0 +1,14 @@ +package br.com.renatoarg.ui.home.adapter + +import androidx.recyclerview.widget.DiffUtil +import br.com.renatoarg.model.pojo.User + +class UsersDiffUtilCallback : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: User, newItem: User): Boolean { + return oldItem == newItem + } + + override fun areContentsTheSame(oldItem: User, newItem: User): Boolean { + return oldItem == newItem + } +} \ No newline at end of file diff --git a/app/src/main/java/br/com/renatoarg/ui/home/adapter/UsersListAdapter.kt b/app/src/main/java/br/com/renatoarg/ui/home/adapter/UsersListAdapter.kt index 8f35a8d..603af0a 100644 --- a/app/src/main/java/br/com/renatoarg/ui/home/adapter/UsersListAdapter.kt +++ b/app/src/main/java/br/com/renatoarg/ui/home/adapter/UsersListAdapter.kt @@ -1,57 +1,40 @@ package br.com.renatoarg.ui.home.adapter -import android.content.Context -import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup -import androidx.recyclerview.widget.RecyclerView -import br.com.renatoarg.R +import androidx.recyclerview.widget.ListAdapter import br.com.renatoarg.model.pojo.User +import br.com.renatoarg.ui.home.adapter.viewholder.ErrorViewHolder import br.com.renatoarg.ui.home.adapter.viewholder.UserOkViewHolder import br.com.renatoarg.ui.home.adapter.viewholder.UsersListInterface +import br.com.renatoarg.ui.home.adapter.viewholder.UsersViewHolder class UsersListAdapter( - private val context: Context, - private var users: List, private val usersInterface: UsersListInterface -) : RecyclerView.Adapter>() { +) : ListAdapter(UsersDiffUtilCallback()) { companion object { private const val TYPE_OK = 0 private const val TYPE_ERROR = 100 } - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder<*> { + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UsersViewHolder { return when(viewType) { - TYPE_OK -> UserOkViewHolder( - LayoutInflater.from(context).inflate(R.layout.item_user, parent, false), - usersInterface - ) + TYPE_OK -> UserOkViewHolder(parent, usersInterface) + TYPE_ERROR -> ErrorViewHolder(parent, usersInterface) else -> throw IllegalArgumentException("Invalid view type") } } override fun getItemViewType(position: Int): Int { - return TYPE_OK - } - - - override fun getItemCount(): Int { - return users.size - } - - override fun onBindViewHolder(holder: BaseViewHolder<*>, position: Int) { - when(holder) { - is UserOkViewHolder -> holder.bind(users[position]) + val firstNameSize = getItem(position).first_name?.length ?: 0 + return when(firstNameSize){ + in 0 .. 5 -> TYPE_OK + else -> TYPE_ERROR } - } - fun updateUsers(usersList: List) { - this.users = usersList - notifyDataSetChanged() } - abstract class BaseViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { - abstract fun bind(item: T) + override fun onBindViewHolder(holder: UsersViewHolder, position: Int) { + holder.bind(getItem(position)) } } diff --git a/app/src/main/java/br/com/renatoarg/ui/home/adapter/viewholder/ErrorViewHolder.kt b/app/src/main/java/br/com/renatoarg/ui/home/adapter/viewholder/ErrorViewHolder.kt new file mode 100644 index 0000000..07996c7 --- /dev/null +++ b/app/src/main/java/br/com/renatoarg/ui/home/adapter/viewholder/ErrorViewHolder.kt @@ -0,0 +1,36 @@ +package br.com.renatoarg.ui.home.adapter.viewholder +import android.text.Spannable +import android.text.SpannableString +import android.text.style.StrikethroughSpan +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.core.text.set +import br.com.renatoarg.R +import br.com.renatoarg.model.pojo.User +import com.bumptech.glide.Glide +import com.bumptech.glide.request.RequestOptions +import kotlinx.android.synthetic.main.item_user.view.* + +class ErrorViewHolder( + parent: ViewGroup, + usersInterface: UsersListInterface +) : UsersViewHolder( + LayoutInflater.from(parent.context).inflate(R.layout.item_error, parent, false), + usersInterface +) { + + override fun bind(user: User) { + super.bind(user) + val name = itemView.name.text + val spannableString = SpannableString(name) + spannableString.setSpan( + StrikethroughSpan(), + 0, + user.first_name?.length ?: 0, + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE + ) + itemView.name.text = spannableString + } + +} + diff --git a/app/src/main/java/br/com/renatoarg/ui/home/adapter/viewholder/UserOkViewHolder.kt b/app/src/main/java/br/com/renatoarg/ui/home/adapter/viewholder/UserOkViewHolder.kt index 98508d7..7780060 100644 --- a/app/src/main/java/br/com/renatoarg/ui/home/adapter/viewholder/UserOkViewHolder.kt +++ b/app/src/main/java/br/com/renatoarg/ui/home/adapter/viewholder/UserOkViewHolder.kt @@ -1,29 +1,23 @@ package br.com.renatoarg.ui.home.adapter.viewholder +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView import androidx.constraintlayout.widget.ConstraintLayout +import androidx.recyclerview.widget.RecyclerView import br.com.renatoarg.R import br.com.renatoarg.model.pojo.User import br.com.renatoarg.ui.home.adapter.UsersListAdapter import com.bumptech.glide.Glide import com.bumptech.glide.request.RequestOptions +import kotlinx.android.synthetic.main.item_user.view.* class UserOkViewHolder( - itemView: View, - var usersInterface: UsersListInterface -) : - UsersListAdapter.BaseViewHolder(itemView) { - - override fun bind(item: User) { - val photo = itemView.findViewById(R.id.photo) - Glide.with(itemView.context).load(item.avatar).apply(RequestOptions().circleCrop()).into(photo) - itemView.findViewById(R.id.name).text = itemView.context.getString(R.string.user_name, item.first_name, item.last_name) - itemView.findViewById(R.id.email).text = item.email - itemView.findViewById(R.id.wrapper).setOnClickListener { - usersInterface.selectUser(item, photo) - } - } - -} + parent: ViewGroup, + usersInterface: UsersListInterface +) : UsersViewHolder( + LayoutInflater.from(parent.context).inflate(R.layout.item_user, parent, false), + usersInterface +) diff --git a/app/src/main/java/br/com/renatoarg/ui/home/adapter/viewholder/UsersViewHolder.kt b/app/src/main/java/br/com/renatoarg/ui/home/adapter/viewholder/UsersViewHolder.kt new file mode 100644 index 0000000..064b76f --- /dev/null +++ b/app/src/main/java/br/com/renatoarg/ui/home/adapter/viewholder/UsersViewHolder.kt @@ -0,0 +1,30 @@ +package br.com.renatoarg.ui.home.adapter.viewholder + +import android.view.View +import androidx.recyclerview.widget.RecyclerView +import br.com.renatoarg.R +import br.com.renatoarg.model.pojo.User +import com.bumptech.glide.Glide +import com.bumptech.glide.request.RequestOptions +import kotlinx.android.synthetic.main.item_user.view.* + +abstract class UsersViewHolder( + itemView : View, + private val usersInterface: UsersListInterface +) : RecyclerView.ViewHolder(itemView) { + open fun bind(user : User){ + with(itemView){ + + Glide.with(itemView.context) + .load(user.avatar) + .apply(RequestOptions().circleCrop()) + .into(photo) + + name.text = itemView.context.getString(R.string.user_name, user.first_name, user.last_name) + email.text = user.email + wrapper.setOnClickListener { + usersInterface.selectUser(user, photo) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/item_error.xml b/app/src/main/res/layout/item_error.xml new file mode 100644 index 0000000..cd0638a --- /dev/null +++ b/app/src/main/res/layout/item_error.xml @@ -0,0 +1,40 @@ + + + + + + + + + + \ No newline at end of file