Ignore an attribute from contains function. I mean if an attribute value changes it still be the same object.
I have implemented tracking of object in RecyclerView android. Now When some product is favourite by clicking a heart icon
. One of it's attribute
isFavourite = true /// become true
Below method get called on onScrollStateChanged
of RecyclerView
private fun trackVisibleItems(visiblePositions: IntRange) {
for (position in visiblePositions) {
if (position != -1) {
trackableCollectionCallback?.getViewedItem(position)?.let {
if(isPresent() && shownTrackablePositions.contains(it).not()){
it.trackView()
trackableCollectionCallback?.onTrackedItem(it,position)
shownTrackablePositions.add(it)
}
}
}
}
}
Now after selecting heart icon
from any product
. An attribute name isFavourite got updated in the database. I want to ignore that variable from contains.
I have tried to write a data class in kotlin and put isFavourite out of the base constructor So that equal , hash etc don't work on it.
But contains function match all attributes. How could I ignore a var from contains.
TrackableObject.kt
abstract class TrackableObject {
abstract fun getClickEventName(): String
abstract fun getViewEventName(): String
abstract fun getTrackParams(): MutableSet<Pair<String, Any>>
fun trackClick() {
Analytics.trackEvent(getClickEventName(), getTrackParams())
}
fun trackView() {
Analytics.trackEvent(getViewEventName(), getTrackParams())
}
}
Moving the property out of the constructor should work. It should look like this:
data class MyItem(
val id: Long,
val foo: String
) {
var isFavourite: Boolean = false
}
However, I think it would be preferable to keep that in your constructor so you don't break your equals
/hashCode
functionality for other purposes, such as using them in a DiffUtil.
In that case, you can use any
instead of contains
. Since you have to go through all the properties manually, I'd break it out into a function to keep your logic more readable.
data class MyItem(
val id: Long,
val foo: String,
var isFavourite: Boolean = false
)
fun Iterable<MyItem>.containsMatch(item: MyItem): Boolean = any {
it.id == item.id && it.foo == item.foo
}
// ...
if(isPresent() && shownTrackablePositions.containsMatch(it).not()){
it.trackView()
trackableCollectionCallback?.onTrackedItem(it,position)
shownTrackablePositions.add(it)
}