Ejemplo de como implementar vista vacia en un RecyclerView usando Kotlin
Created
March 26, 2020 14:02
-
-
Save webserveis/aac47fc8ff97b69b52417a68fc6d7101 to your computer and use it in GitHub Desktop.
Empty View for Android's RecyclerView
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.view.View | |
import androidx.recyclerview.widget.RecyclerView | |
abstract class BaseViewHolder<T>(itemView: View) : RecyclerView.ViewHolder(itemView) { | |
abstract fun bind(item: T) | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.* | |
data class DeviceModel( | |
val status: Boolean, | |
val name: String?, | |
val macAddress: String, | |
val detectDate: Date?, | |
val uid: String = UUID.randomUUID().toString() | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
:)