I'm using diff utils to update my recycler view (live data from view model returns a list), I have an item decoration that adds a large amount of padding to the last element in the list but as diff utils updates the recycler view properly by calling notifyItemInserted and not notifyDataSetChanged, the decoration is only applied to the last element ADDED so all my items end up with a large amount of padding on the end, if I add an item to my recycler view and call notify dataset changed the adapter rebuilds all the items and the padding is only on the last element (which is what I want) also if i add the same item twice it adds it before the last added for instance if i have a list of 1,2,3 and i add another 3 it gets added before the existing 3 so 1,2,3b,3a, is there any way to have a little more control over this?
Item decoration
public class PredictionsHorizontalSpaceCardDecoration extends RecyclerView.ItemDecoration {
private final int horizontalSpace;
private final int endSpace;
public PredictionsHorizontalSpaceCardDecoration(int horizontalSpace, int endSpace) {
this.horizontalSpace = horizontalSpace;
this.endSpace = endSpace;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
Log.d("Deco", "parent child count " + (parent.getChildCount() - 1) + " position " + parent.getChildAdapterPosition(view));
outRect.right = horizontalSpace;
outRect.top = horizontalSpace;
outRect.bottom = horizontalSpace;
outRect.left = horizontalSpace;
if (parent.getChildAdapterPosition(view) == parent.getChildCount() - 1){
outRect.right = endSpace;
}
}
@Override
public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull State state) {
super.onDraw(c, parent, state);
}
}
Diff utils
public class MyDiffCallback extends DiffUtil.Callback{
List<Card> oldCards;
List<Card> newCards;
String TAG = "diffUtils";
public MyDiffCallback(List<Card> newCards, List<Card> oldCards) {
this.newCards = newCards;
this.oldCards = oldCards;
}
@Override
public int getOldListSize() {
return oldCards.size();
}
@Override
public int getNewListSize() {
return newCards.size();
}
@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
boolean areItemsTheSame = oldCards.get(oldItemPosition).getCardId() == newCards.get(newItemPosition).getCardId();
Log.d(TAG,"areItemsTheSame " + areItemsTheSame);
return oldCards.get(oldItemPosition).getCardId() == newCards.get(newItemPosition).getCardId();
}
@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
boolean areItemsTheSame = oldCards.get(oldItemPosition).equals(newCards.get(newItemPosition));
Log.d(TAG,"areContentsTheSame " + areItemsTheSame);
return oldCards.get(oldItemPosition).equals(newCards.get(newItemPosition));
}
@Nullable
@Override
public Object getChangePayload(int oldItemPosition, int newItemPosition) {
//you can return particular field for changed item.
Log.d(TAG,"getChangePayload ");
return super.getChangePayload(oldItemPosition, newItemPosition);
// return newCards.get(newItemPosition).getCardId();
}
}
updated from recycler view adapter
public class CalculateDiffUtils extends AsyncTask<Void, Void, DiffUtil.DiffResult> {
private List<Card> oldCardList;
private List<Card> newCardList;
CalculateDiffUtils(List<Card> oldCardList, List<Card> newCardList) {
this.oldCardList = oldCardList;
this.newCardList = newCardList;
}
@Override
protected DiffUtil.DiffResult doInBackground(Void... params) {
return DiffUtil.calculateDiff(new MyDiffCallback(newCardList, oldCardList));
}
@Override
protected void onPostExecute(DiffUtil.DiffResult diffResult) {
super.onPostExecute(diffResult);
dispatchUpdates(diffResult, newCardList);
}
}
public void dispatchUpdates(DiffUtil.DiffResult diffResult, List<Card> newCardList){
this.cardList.clear();
this.cardList.addAll(newCardList);
diffResult.dispatchUpdatesTo(this);
}