https://kotlinlang.org logo
#android-architecture
Title
# android-architecture
u

ursus

06/01/2019, 5:49 PM
is there some sane solution other than codegen?
j

joelpedraza

06/03/2019, 2:33 PM
Maybe I’m misunderstanding the question. In
DiffUtil.Callback
areItemsTheSame
checks identity equality
areContentsTheSame
checks visual equality The adapter is only notified of changes if the return values of both are true
areContentsTheSame
is _only called for elements in which
areItemsTheSame
has returned
true
@ursus
When `areItemsTheSame`returns `true `for two items and
areContentsTheSame
returns false for them,
DiffUtil
calls this method to get a payload about the change.
Which makes sense, you only need a diff payload when the items have the same identity, but different contents
u

ursus

06/03/2019, 3:32 PM
yes, im talking about the getChangePayload
problem is that you have to have a whitelist of fields in the payload function
however, this needs to be a complete list, you cannot forget to add here newly added model field
because this way that field value wont be updated in the view
= codgen is needed @joelpedraza
j

joelpedraza

06/03/2019, 6:44 PM
The payload is any arbitrary object. I’m not sure what you mean by field whitelist
u

ursus

06/03/2019, 8:40 PM
Copy code
@Nullable
    @Override
    public Object getChangePayload(int oldItemPosition, int newItemPosition) {
        Contact newContact = newList.get(newItemPosition);
        Contact oldContact = oldList.get(oldItemPosition);

        Bundle diff = new Bundle();
        if(!newContact.getName().equals(oldContact.getName())){
            diff.putString("name", newContact.getName());
        }
        if(!newContact.getPhonenumber().equals (oldContact.getPhonenumber())){
            diff.putString("phone", newContact.getPhonenumber());
        }
        if (diff.size()==0){
            return null;
        }
        return diff;
    }
this is like very common what people do, I copy pasted it from some tutorial
the problem with it that it has the white list of checking for name & phone number change
so when you add a Image url to the model next time in future, and you forget to add it here; and Name and Image change for some object, your whitelist will only catch the Name change and your Image wont be refreshed
j

joelpedraza

06/04/2019, 1:05 PM
Ah now I see what you mean. It does seem like a good use case for codegen. If you want a hand written solution, consider some sort of double-dispatch, like a visitor pattern. Updating the model means adding a new
visit
method, then it’s a compile error unless you add an implementation for the new method to all your visitors
WARNING: OPINION
Using a bundle is weird. What’s the purpose of even having the
Contact
type that stores all the data, only to stuff it into the bundle.
I’d prefer an
EnumSet
, then you can pattern match with a
when
expression and non-exhastive matching will be a compiler error That would come at the development cost of declaring a new enum for each view holder. This dosent seem much higher than declaring string constants though. Also the runtime (bytecode) cost of adding new Class
@ursus
u

ursus

06/04/2019, 9:40 PM
@joelpedraza im not sure how would you enfore the visitor, one still has to add it
j

joelpedraza

06/06/2019, 2:06 PM
You cant really enforce that the visitor has a method for each field. If you put the declaration of the visitor as a nested class of the data type, and comments to update it when adding a field: you’ll probably be OK with just convention
u

ursus

06/07/2019, 6:16 AM
Yea, cached reflection will probably be a better solution
2 Views