RecyclerView - для изменения значка выбранного элемента требуется два щелчка мышью
Я работаю над почтовым приложением, в котором пользователь может отправлять одну и ту же почту нескольким контактам. Когда я открываю список контактов, я хочу иметь возможность нажимать на пользователя, и его изображение в профиле должно быть заменено отмеченным значком.
Когда я щелкаю, чтобы выбрать пользователя, значок мигает, и он не меняется при первом нажатии на него. Во второй раз, когда я нажимаю на него, изображение все еще мерцает, но затем изменяется на "проверено", и каждый раз, когда я нажимаю на этого пользователя, оно будет мерцать, но делать то, что я хочу - становиться отмеченным / не отмеченным.
Я использую это руководство как руководство, но оно не документировано так хорошо, как должно быть. Некоторые методы объясняются одним словом, другие даже не упоминаются, но появляются в коде. Я искал другие учебные пособия и действительно нашел много одинаковых ( идентичных) примеров, не углубляясь даже немного глубже, чем оригинал.
Adapter.java:
@Override
public void onBindViewHolder(final ChooseContactsAdapter.ChooseContactsViewHolder holder, final int position) {
final Contact contact = contactList.get(position);
holder.userName.setText(contact.getUserName());
TextDrawable.IBuilder builder = TextDrawable.builder()
.beginConfig()
.withBorder(0)
.toUpperCase()
.endConfig()
.round();
ColorGenerator generator = ColorGenerator.MATERIAL;
// generate color based on a key (same key returns the same color), useful for list/grid views
int color = generator.getColor(contact.getUserId());
textDrawable = builder.build(contactList.get(position).getUserName().substring(0, 1), color);
holder.thumbNail.setImageDrawable(textDrawable);
holder.contactId = contact.getUserId();
// display profile image
applyProfilePicture(holder, contact);
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// toggle selection
toggleSelection(position);
// Change background color of the selected items in list view
holder.itemView.setBackgroundColor(selectedItems.get(position) ? 0x9934B5E4 : Color.TRANSPARENT);
// check if item still exists
if (position != RecyclerView.NO_POSITION) {
Contact contact = contactList.get(position);
Toast.makeText(v.getContext(), "You clicked " + contact.getUserName(), Toast.LENGTH_SHORT).show();
}
// handle icon animation
applyIconAnimation(holder, position);
}
});
}
private void applyProfilePicture(ChooseContactsViewHolder holder, Contact contact) {
Picasso.with(context)
.load(AppConfig.URL_PROFILE_PHOTO + contact.getThumbnailUrl())
.placeholder(textDrawable)
.error(textDrawable)
.transform(new CircleTransform())
.into(holder.thumbNail);
}
private void applyIconAnimation(ChooseContactsViewHolder holder, int position) {
if (selectedItems.get(position, false)) {
holder.iconFront.setVisibility(View.GONE);
resetIconYAxis(holder.iconBack);
holder.iconBack.setVisibility(View.VISIBLE);
holder.iconBack.setAlpha(1);
if (currentSelectedIndex == position) {
FlipAnimator.flipView(context, holder.iconBack, holder.iconFront, true);
resetCurrentIndex();
}
} else {
holder.iconBack.setVisibility(View.GONE);
resetIconYAxis(holder.iconFront);
holder.iconFront.setVisibility(View.VISIBLE);
holder.iconFront.setAlpha(1);
if ((reverseAllAnimations && animationItemsIndex.get(position, false)) || currentSelectedIndex == position) {
FlipAnimator.flipView(context, holder.iconBack, holder.iconFront, false);
resetCurrentIndex();
}
}
}
private void toggleSelection(int pos) {
currentSelectedIndex = pos;
if (selectedItems.get(pos, false)) {
selectedItems.delete(pos);
animationItemsIndex.delete(pos);
} else {
selectedItems.put(pos, true);
animationItemsIndex.put(pos, true);
}
notifyItemChanged(pos);
}
1 ответ
Там нет необходимости звонить notifyItemChanged
на toggleSelection
метод. Вы уже меняете элемент вручную с помощью анимации.
призвание notifyItemChanged
это то, что вызывает мерцание, потому что это мешает анимации.