Skip to content

Instantly share code, notes, and snippets.

@webserveis
Created March 26, 2020 14:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save webserveis/aac47fc8ff97b69b52417a68fc6d7101 to your computer and use it in GitHub Desktop.
Save webserveis/aac47fc8ff97b69b52417a68fc6d7101 to your computer and use it in GitHub Desktop.
Empty View for Android's RecyclerView

Empty View for Android's RecyclerView

Ejemplo de como implementar vista vacia en un RecyclerView usando Kotlin

import android.view.View
import androidx.recyclerview.widget.RecyclerView
abstract class BaseViewHolder<T>(itemView: View) : RecyclerView.ViewHolder(itemView) {
abstract fun bind(item: T)
}
import java.util.*
data class DeviceModel(
val status: Boolean,
val name: String?,
val macAddress: String,
val detectDate: Date?,
val uid: String = UUID.randomUUID().toString()
)
private lateinit var mAdapter: MyListAdapter
...
fun initRecyclerView() {
mAdapter = MyListAdapter()
mAdapter.emptyText = getString(R.string.allowed_devices_empty)
list.adapter = mAdapter
}
...
fabAdd.setOnClickListener {
val dataSet: MutableList<DeviceModel> = arrayListOf()
dataSet.add(DeviceModel(true, "aaa22", "ff", null, "device1"))
dataSet.add(DeviceModel(true, "bbb", "ff", null, "device2"))
dataSet.add(DeviceModel(true, "ccc", "ff", null, "device3"))
mAdapter.submitList(dataSet)
}
fabAdd.setOnLongClickListener {
mAdapter.clearData()
true
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center_horizontal"
android:padding="8dp"
android:paddingStart="?listPreferredItemPaddingStart"
android:paddingEnd="?listPreferredItemPaddingEnd"
android:text="@string/allowed_devices_empty"
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
android:textColor="?android:textColorSecondary" />
</RelativeLayout>
class MyDiffCallback(
private val oldItems: List<DeviceModel>,
private val newItems: List<DeviceModel>
) : DiffUtil.Callback() {
override fun getOldListSize(): Int = oldItems.size
override fun getNewListSize(): Int = newItems.size
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean =
oldItems[oldItemPosition].uid == newItems[newItemPosition].uid
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean =
oldItems[oldItemPosition] == newItems[newItemPosition]
}
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.webserveis.mqtthomepresence.R
import com.webserveis.mqtthomepresence.commons.BaseViewHolder
import com.webserveis.mqtthomepresence.models.DeviceModel
class MyListAdapter : RecyclerView.Adapter<BaseViewHolder<*>>() {
private var dataSet: MutableList<DeviceModel> = arrayListOf()
var emptyText: String = "No data"
companion object {
private val TAG = MyListAdapter::class.java.simpleName
private const val VIEW_TYPE_EMPTY = 0
private const val VIEW_TYPE_ITEM = 1
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = when (viewType) {
VIEW_TYPE_EMPTY -> EmptyViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.item_empty, parent, false)
)
VIEW_TYPE_ITEM -> MyViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.simple_list_item_2, parent, false)
)
else -> throw IllegalArgumentException("Invalid view type")
}
override fun onBindViewHolder(holder: BaseViewHolder<*>, position: Int) {
if (position != RecyclerView.NO_POSITION) {
when (holder) {
is EmptyViewHolder -> holder.bind(emptyText)
is MyViewHolder -> holder.bind(dataSet[position])
else -> throw IllegalArgumentException("Invalid ViewHolder")
}
}
}
fun clearData() {
val size: Int = dataSet.size
dataSet.clear()
notifyItemRangeRemoved(0, size)
}
fun submitList(newData: List<DeviceModel>) {
val needNotifyDataChanged = dataSet.size == 0
val diffResult = DiffUtil.calculateDiff(MyDiffCallback(dataSet, newData))
diffResult.dispatchUpdatesTo(this)
dataSet.clear()
dataSet.addAll(newData)
if (needNotifyDataChanged) notifyItemChanged(dataSet.size)
}
inner class MyViewHolder(itemView: View) : BaseViewHolder<DeviceModel>(itemView) {
private val tvText1 = itemView.findViewById(android.R.id.text1) as TextView
private val tvText2 = itemView.findViewById(android.R.id.text2) as TextView
override fun bind(item: DeviceModel) {
tvText1.text = item.name
tvText2.text = item.macAddress
}
}
inner class EmptyViewHolder(itemView: View) : BaseViewHolder<String>(itemView) {
private val tvText1 = itemView.findViewById(android.R.id.text1) as TextView
override fun bind(item: String) {
tvText1.text = item
}
}
override fun getItemViewType(position: Int): Int = if (dataSet.count() == 0) {
VIEW_TYPE_EMPTY
} else {
VIEW_TYPE_ITEM
}
override fun getItemCount(): Int {
return when (val count = dataSet.size) {
0 -> 1
else -> count
}
}
}
@itsvdnt
Copy link

itsvdnt commented Mar 6, 2021

:)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment