areItemsTheSame of DiffUtils вызывается несколько раз при обновлении одного элемента? - PullRequest
0 голосов
/ 03 июля 2019

MainActivity

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final RecyclerView recyclerView = findViewById(R.id.rv_diff_util);
    final Button btnUpdater = findViewById(R.id.btn_updater);

    final PlacesAdapter placesAdapter = new PlacesAdapter(createPlacesList());
    recyclerView.setLayoutManager(new LinearLayoutManager(this, RecyclerView.VERTICAL, false));
    recyclerView.setAdapter(placesAdapter);

    btnUpdater.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            placesAdapter.updateItems(createAlteredPlacesList());
        }
    });
}

private ArrayList<Place> createPlacesList() {
    ArrayList<Place> places = new ArrayList<>();
    places.add(new Place(1, "Delhi", "India"));
    return places;
}

private ArrayList<Place> createAlteredPlacesList() {
    ArrayList<Place> places = new ArrayList<>();
    places.add(new Place(1, "Kerala", "India"));
    return places;
  }
}

PlacesAdapter

public class PlacesAdapter extends RecyclerView.Adapter<PlacesAdapter.PlaceViewHolder> {

private ArrayList<Place> places;

 PlacesAdapter(ArrayList<Place> places) {
    this.places = places;
}

void updateItems(ArrayList<Place> newPlacesList) {
    final PlacesDiffCallback diffCallback = new PlacesDiffCallback(this.places, newPlacesList);
    final DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(diffCallback);
    this.places.clear();
    this.places.addAll(newPlacesList);
    diffResult.dispatchUpdatesTo(this);
}

@NonNull
@Override
public PlaceViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
    final View view = inflater.inflate(R.layout.item_place, parent, false);
    return new PlaceViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull PlaceViewHolder holder, int position) {
    holder.bindItems();
}

@Override
public void onBindViewHolder(@NonNull PlaceViewHolder holder, int position, @NonNull List<Object> payloads) {
    if (!payloads.isEmpty()) {
        Bundle bundle = (Bundle) payloads.get(0);
        if (bundle.size() != 0) {
            String city= bundle.getString("city");
            if (city != null) {
                holder.tvCity.setText(city);
            }

            String country= bundle.getString("country");
            if (country!= null) {
                holder.tvName.setText(country);
            }
        }
    } else {
        super.onBindViewHolder(holder, position, payloads);
    }
}

@Override
public int getItemCount() {
    return places.size();
}

class PlaceViewHolder extends RecyclerView.ViewHolder {
    TextView tvCity, tvCountry;

     PlaceViewHolder(@NonNull View itemView) {
        super(itemView);
        tvCity= itemView.findViewById(R.id.tv_city);
        tvCountry= itemView.findViewById(R.id.tv_country);
    }

    private void bindItems() {
        tvCity.setText(places.get(getAdapterPosition()).getCity());
        tvCountry.setText(places.get(getAdapterPosition()).getCountry());
     }
  }
 }

PlacesDiffCallback

public class PlacesDiffCallback extends DiffUtil.Callback {
private int counter = 0;

private final ArrayList<Place> oldPlaces;
private final ArrayList<Place> newPlaces;

public PlacesDiffCallback(ArrayList<Place> oldPlaces, ArrayList<Place> newPlaces) {
    this.oldPlaces = oldPlaces;
    this.newPlaces = newPlaces;
}

@Override
public int getOldListSize() {
    return oldPlaces.size();
}

@Override
public int getNewListSize() {
    return newPlaces.size();
}

@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
    Log.d("Counter",++counter +"");
    return oldPlaces.get(oldItemPosition).getId() == newPlaces.get(newItemPosition).getId();
}

@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
    Place oldPlace = oldPlaces.get(oldItemPosition);
    Place newPlace = newPlaces.get(newItemPosition);
    return oldPlace.getCity().equals(newPlace.getCity()) && oldPlace.getCountry().equals(newPlace.getCountry());
}

@Override
public Object getChangePayload(int oldItemPosition, int newItemPosition) {
    Place oldPlace = oldPlaces.get(oldItemPosition);
    Place newPlace = newPlaces.get(newItemPosition);
    Bundle bundle = new Bundle();
    if (!oldPlace.getCity().equals(newPlace.getCity())) {
        bundle.putString("city", newPlace.getCity());
    }
    if (!oldPlace.getCountry().equals(newPlace.getCountry())) {
        bundle.putString("country", newPlace.getCountry());
    }
    return bundle;
   }
  }

Я получаю areItemsTheSame, который вызывается дважды, и когда срабатывает areContentsTheSame & getChangePayload, оба списка имеют одинаковые элементы, обновление не происходит.

...