Trilean? A three-value boolean at used

Image for post
Image for post

I was using DiffUtil.Callback and coding the areItemTheSame and areContentTheSame function. This is a very useful Class Function for RecyclerView multiple rows changes animation as per my story here.

The two functions are used to determined for a given old and new position, are they the same row, and if their content are the same.

My recyclerView is made such that, it has a header, title-row, the content (that varies in size) and end with footer, as illustrated below.

Image for post
Image for post

The Comparison

So with that, you could imagine my comparison if the Item is the same would be

@Override
public boolean areItemsTheSame(int oldPos, int newPos) {
if (isHeaderPos(oldPos) || isHeaderPos(newPos)) {
return isHeaderPos(oldPos) == isHeaderPos(newPos));
} else if (isTitlePos(oldPos) || isTitlePos(newPos)) {
return isTitlePos(oldPos) == isTitlePos(newPos));
} else if (isFooterPos(oldPos) || isFooterPos(newPos)) {
return isFooterPos(oldPos) == isFooterPos(newPos));
}

Item oldItem = getItem(oldPos);
Item newItem = getItem(newPos);
return (oldItem.getId() == newItem.getId());
}

The the comparison for if the Item has the same content (in my case I threat different item definitely content different)

@Override
public boolean areContentsTheSame(int oldPos, int newPos) {
if (isHeaderPos(oldPos) || isHeaderPos(newPos)) {
return isHeaderPos(oldPos) == isHeaderPos(newPos));
} else if (isTitlePos(oldPos) || isTitlePos(newPos)) {
return isTitlePos(oldPos) == isTitlePos(newPos));
} else if (isFooterPos(oldPos) || isFooterPos(newPos)) {
return isFooterPos(oldPos) == isFooterPos(newPos));
}

Item oldItem = getItem(oldPos);
Item newItem = getItem(newPos);
if (oldItem.getId() != newItem.getId()) return false; return oldItem.getContent() == newItem.getContent();
}

Duplicate Codes?

Clearly, there are duplicate codes in this two functions as shown below.

if (isHeaderPos(oldPos) || isHeaderPos(newPos)) {
return isHeaderPos(oldPos) == isHeaderPos(newPos));
} else if (isTitlePos(oldPos) || isTitlePos(newPos)) {
return isTitlePos(oldPos) == isTitlePos(newPos));
} else if (isFooterPos(oldPos) || isFooterPos(newPos)) {
return isFooterPos(oldPos) == isFooterPos(newPos));
}

Item oldItem = getItem(oldPos);
Item newItem = getItem(newPos);
if (oldItem.getId() != newItem.getId()) return false;

But I can’t easily refactor them into a function. They are not really returning something, nor are they Boolean.

If look carefully, they are actually, TRUE, FALSE, or UNKNOWN. This is called Trilean, or Three-Value Logic.

So how could we handle Trilean?

Most people would think of Enum. But I’m lazy to introduce an enum. I still want to use Boolean for it. This is possible, because a Boolean value is either TRUE, FALSE and we could set it to NULL.

Now we could extract this common code into a private function as below

@Nullable
private Boolean isTheSame(int oldPos, int newPos) {
if (isHeaderPos(oldPos) || isHeaderPos(newPos)) {
return isHeaderPos(oldPos) == isHeaderPos(newPos));
} else if (isTitlePos(oldPos) || isTitlePos(newPos)) {
return isTitlePos(oldPos) == isTitlePos(newPos));
} else if (isFooterPos(oldPos) || isFooterPos(newPos)) {
return isFooterPos(oldPos) == isFooterPos(newPos));
}

Item oldItem = getItem(oldPos);
Item newItem = getItem(newPos);
if (oldItem.getId() != newItem.getId()) return false;
return null;
}

And now, we have simplified our overriden functions as below.

@Override
public boolean areItemsTheSame(int oldPos, int newPos) {
Boolean isSame = isTheSame(oldPos, newPos);
return (isSame != null)? isSame : true;
}
@Override
public boolean areContentsTheSame(int oldPos, int newPos) {
Boolean isSame = isTheSame(oldPos, newPos);
if (isSame != null)? return isSame;
Item oldItem = getItem(oldPos);
Item newItem = getItem(newPos);
return oldItem.getContent() == newItem.getContent();
}

Hint: You don’t really need to do the refactor yourselves if you use Android Studio. Just select the code you want to refactor, and press Alt-Command-M, type in the name, and Bingo!

Written by

Passionate about learning, and sharing mobile development and others https://twitter.com/elye_project https://www.facebook.com/elye.proj

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store