Ich habe mehrere Bilder RecyclerView
mit animierten Ansichten (blinkende weiße Kreise) in Elemente. Während recyclerView
Scroll-Animationen können nach dem Zufallsprinzip aufhören zu arbeiten.Unendliche Animation in RecyclerView stoppt nach dem Scrollen
Ich dachte dieses Problem ist mit onCreateViewHolder
oder onBindViewHolder
verbunden, aber dieses Problem reproduziert, auch wenn keine dieser Methoden aufgerufen wurde.
Animation Wiederholungszahl auf unendlich eingestellt, clearAnimation()
nur in onBindViewHolder
aufgerufen.
Mein Adaptercode:
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.TextView;
import com.annimon.stream.Stream;
import com.squareup.picasso.Picasso;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.TimeZone;
import butterknife.Bind;
import butterknife.ButterKnife;
public class ChatAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements View.OnClickListener {
private final int avatarSize;
private List<IncomingTextMessage> chatMessages = new ArrayList<>();
private User appOwner;
private User wallOwner;
private int MESSAGE_TYPE_MY = 0;
private int MESSAGE_TYPE_INTERLOCUTOR = 1;
private SimpleDateFormat timeFormat;
private SimpleDateFormat dateFormat;
private static final String TAG = "ChatAdapter";
private int bindViewHolderCallCounter = 0;
public ChatAdapter(User appOwner, User wallOwner, Context context) {
this.appOwner = appOwner;
this.wallOwner = wallOwner;
avatarSize = context.getResources().getDimensionPixelSize(R.dimen.post_avatar_size);
timeFormat = new SimpleDateFormat(context.getString(R.string.time_format));
dateFormat = new SimpleDateFormat(context.getString(R.string.server_date_parsing_format));
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Random rnd = new Random();
int color = Color.argb(255, rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
View v;
if (viewType == MESSAGE_TYPE_MY) {
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_my_chat_message, parent, false);
v.setBackgroundColor(color);
return new MyMessageViewHolder(v);
} else { //viewType == MESSAGE_TYPE_INTERLOCUTOR
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_interlocutor_chat_message, parent, false);
v.setBackgroundColor(color);
return new InterlocutorMessageViewHolder(v);
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
bindViewHolderCallCounter++;
Log.d(TAG, "onBindViewHolder:" + chatMessages.get(position).getText() + " " + (getItemViewType(position) == MESSAGE_TYPE_MY));
if (getItemViewType(position) == MESSAGE_TYPE_MY) {
MyMessageViewHolder myMessageViewHolder = (MyMessageViewHolder) holder;
setUserAvatar(appOwner, myMessageViewHolder.ivUserAvatar);
myMessageViewHolder.ivUserAvatar.setTag(appOwner);
myMessageViewHolder.ivUserAvatar.setOnClickListener(this);
myMessageViewHolder.tvText.setText(chatMessages.get(position).getText() +" bindViewHolderCallCounter " + bindViewHolderCallCounter);
myMessageViewHolder.tvTime.setText(formatTime(chatMessages.get(position).getDateTime()));
setupMessageState(myMessageViewHolder, chatMessages.get(position));
} else /*if (getItemViewType(position) == MESSAGE_TYPE_INTERLOCUTOR)*/ {
InterlocutorMessageViewHolder interlocutorMessageViewHolder = (InterlocutorMessageViewHolder) holder;
setUserAvatar(wallOwner, interlocutorMessageViewHolder.ivUserAvatar);
interlocutorMessageViewHolder.ivUserAvatar.setTag(wallOwner);
interlocutorMessageViewHolder.ivUserAvatar.setOnClickListener(this);
interlocutorMessageViewHolder.tvText.setText(chatMessages.get(position).getText());
interlocutorMessageViewHolder.tvTime.setText(formatTime(chatMessages.get(position).getDateTime()));
}
}
private void setupMessageState(MyMessageViewHolder myMessageViewHolder, IncomingTextMessage message) {
Log.d(TAG, "setupMessageState");
Animation animation = AnimationUtils.loadAnimation(myMessageViewHolder.ivUserAvatar.getContext(), R.anim.fade_out_in_chat_circle);
myMessageViewHolder.vMessageStatusAwaitingSending.clearAnimation();
myMessageViewHolder.vMessageStatusAwaitingReading.clearAnimation();
myMessageViewHolder.vMessageStatusAwaitingSending.clearAnimation();
switch (message.getState()) {
case MessageNotification.SENT: {
Log.d(TAG, "MessageNotification.SENT" + message.getText());
myMessageViewHolder.vMessageStatusAwaitingSending.setVisibility(View.VISIBLE);
myMessageViewHolder.vMessageStatusAwaitingReading.setVisibility(View.INVISIBLE);
myMessageViewHolder.vMessageStatusAwaitingSending.setVisibility(View.INVISIBLE);
myMessageViewHolder.vMessageStatusAwaitingSending.setAnimation(animation);
break;
}
case MessageNotification.RECEIVED:
{
Log.d(TAG, "MessageNotification.RECEIVED" + message.getText());
myMessageViewHolder.vMessageStatusAwaitingSending.setVisibility(View.VISIBLE);
myMessageViewHolder.vMessageStatusAwaitingReading.setVisibility(View.VISIBLE);
myMessageViewHolder.vMessageStatusAwaitingSending.setVisibility(View.INVISIBLE);
myMessageViewHolder.vMessageStatusAwaitingReading.setAnimation(animation);
break;
}
case MessageNotification.DELIEVERED:
{
Log.d(TAG, "MessageNotification.DELIEVERED" + message.getText());
myMessageViewHolder.vMessageStatusAwaitingSending.setVisibility(View.VISIBLE);
myMessageViewHolder.vMessageStatusAwaitingReading.setVisibility(View.VISIBLE);
myMessageViewHolder.vMessageStatusAwaitingSending.setVisibility(View.VISIBLE);
myMessageViewHolder.vMessageStatusAwaitingReading.setAnimation(animation);
break;
}
case MessageNotification.READ:
{
Log.d(TAG, "MessageNotification.READ" + message.getText());
myMessageViewHolder.vMessageStatusAwaitingSending.setVisibility(View.VISIBLE);
myMessageViewHolder.vMessageStatusAwaitingReading.setVisibility(View.VISIBLE);
myMessageViewHolder.vMessageStatusAwaitingSending.setVisibility(View.VISIBLE);
break;
}
}
}
private String formatTime(String severDate) {
try {
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
return timeFormat.format(dateFormat.parse(severDate));
} catch (ParseException e) {
e.printStackTrace();
Log.e(TAG, "Time string parsing error :" + severDate);
return "";
}
}
@Override
public int getItemViewType(int position) {
if (chatMessages.get(position).getAuthorId().equals(String.valueOf(appOwner.getId())))
return MESSAGE_TYPE_MY;
else return MESSAGE_TYPE_INTERLOCUTOR;
}
private void setUserAvatar(BaseUser user, ImageView imageView) {
if (user != null && user.getPrimaryImageUrl() != null && !user.getPrimaryImageUrl().isEmpty()) {
Picasso.with(imageView.getContext())
.load(user.getPrimaryImageUrl())
.error(R.drawable.ic_user_avatar_128)
.centerCrop()
.resize(avatarSize, avatarSize)
.transform(new RoundedTransformation())
.into(imageView);
} else {
imageView.setImageResource(R.drawable.ic_user_avatar_128);
}
}
/* public void addNewUsers(List<BaseUser> newUsers) {
this.chatMessages = newUsers;
this.notifyDataSetChanged();
}*/
public void addMessage(IncomingTextMessage incomingTextMessage) {
this.chatMessages.add(incomingTextMessage);
notifyDataSetChanged();
}
public void changeMessageState(MessageNotification notification) {
Stream.of(chatMessages)
.filter(message -> message.getId().equals(notification.getMessageId()))
.forEach(message ->
{
message.setState(notification.getState());
notifyItemChanged(chatMessages.indexOf(message));
});
}
@Override
public int getItemCount() {
return chatMessages.size();
}
@Override
public long getItemId(int position) {
return chatMessages.get(position).getId().hashCode();
}
@Override
public void onClick(View view) {
if (view.getTag() instanceof User) {
User user = (User) view.getTag();
Intent intent = new Intent(view.getContext(), MainActivity.class);
intent.putExtra(Config.USER_STRING_EXTRA, user.getId());
view.getContext().startActivity(intent);
}
}
public void addMessages(ArrayList<IncomingTextMessage> incomingTextMessages) {
chatMessages.addAll(incomingTextMessages);
this.notifyDataSetChanged();
}
class MyMessageViewHolder extends RecyclerView.ViewHolder {
@Bind(R.id.vMessageStatusAwaitingSending)
View vMessageStatusAwaitingSending;
@Bind(R.id.vMessageStatusAwaitingDelivering)
View vMessageStatusAwaitingDelivering;
@Bind(R.id.vMessageStatusAwaitingReading)
View vMessageStatusAwaitingReading;
@Bind(R.id.ivUserAvatar)
ImageView ivUserAvatar;
@Bind(R.id.tvText)
TextView tvText;
@Bind(R.id.tvTime)
TextView tvTime;
public MyMessageViewHolder(View view) {
super(view);
ButterKnife.bind(this, view);
}
}
class InterlocutorMessageViewHolder extends RecyclerView.ViewHolder {
@Bind(R.id.ivUserAvatar)
ImageView ivUserAvatar;
@Bind(R.id.tvText)
TextView tvText;
@Bind(R.id.tvTime)
TextView tvTime;
public InterlocutorMessageViewHolder(View view) {
super(view);
ButterKnife.bind(this, view);
}
}
}
Blinzeln Animation xml
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="650"
android:fromAlpha="1.0"
android:repeatMode="reverse"
android:repeatCount="infinite"
android:toAlpha="0.1" />
hat für mich gearbeitet! –
Das hat auch für mich funktioniert. Kann jedoch jemand erklären, warum onBindViewHolder nicht aufgerufen wird, wenn es wieder angefügt wird? –