First of all sorry for my poor English.
I have a problem with the RecyclerView
. I have a layout with EditText
, submit button and a RecyclerView
.
I can enter some text into EditText
, then I click on submit and text is added to RecyclerView
. Problem is that if there are many messages, then the RecyclerView
goes crazy. It stops displaying right messages, it messes up with the order of messages and so on.
If I set holder.setIsRecyclable(false);
everything seems to work fine, but this is a poor solution in my humble opinion.
For the layout of a single item, I use custom LinearLayout
view which may cause the problem here, but I'm not sure of it.
How to extort on the RecyclerView
to preserve right order of added items?
Here's the adapter of my RecyclerView
.
public class MessagesAdapter extends RecyclerView.Adapter<MessagesAdapter.RecyclerViewHolder> {
private List<String> messagesList = new LinkedList<>();
public MessagesAdapter() {
for (int i = 0; i < 13; ++i) {
messagesList.add(String.valueOf(i));
}
}
@Override
public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new RecyclerViewHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.message_list_item, parent, false));
}
@Override
public void onBindViewHolder(RecyclerViewHolder holder, int position) {
String message = messagesList.get(position);
holder.mHeartBeatMessage.setText(message);
// holder.setIsRecyclable(false);
}
@Override
public int getItemCount() {
return messagesList.size();
}
void addItem(String message) {
this.messagesList.add(message);
}
static class RecyclerViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.heartBeatMessage)
protected HeartBeat mHeartBeatMessage;
RecyclerViewHolder(View view) {
super(view);
ButterKnife.bind(this, view);
}
}
}
I've found out that my Custom View generates the problem. I probably overworked it in a bad manner.
Here's my custom view which is held in adapter.
public class HeartBeat extends LinearLayout {
String mText = "";
public HeartBeat(Context context) {
super(context);
}
public HeartBeat(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public HeartBeat(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
/**
* Initialize main variables.
*/
private void init(Context context, @Nullable AttributeSet attrs) {
if (attrs != null) {
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.HeartBeat,
0, 0);
try {
mText = a.getString(R.styleable.HeartBeat_text);
} finally {
a.recycle();
}
}
ImageView heartBeat = new ImageView(context);
heartBeat.setBackgroundResource(R.drawable.bg_chat_heartbeat);
heartBeat.setImageResource(R.drawable.heartbeat);
ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(0, 0);
layoutParams.width = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 60, getResources().getDisplayMetrics());
layoutParams.height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, getResources().getDisplayMetrics());
heartBeat.setLayoutParams(layoutParams);
addView(heartBeat);
Drawable drawable = heartBeat.getDrawable();
if (drawable instanceof AnimatedVectorDrawableCompat) {
((AnimatedVectorDrawableCompat) drawable).registerAnimationCallback(new Animatable2Compat.AnimationCallback() {
@Override
public void onAnimationEnd(Drawable drawable) {
super.onAnimationEnd(drawable);
HeartBeat.this.removeAllViews();
HeartBeat.this.addTextView(context);
}
});
((AnimatedVectorDrawableCompat) drawable).start();
} else if (drawable instanceof AnimatedVectorDrawable) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
((AnimatedVectorDrawable) drawable).registerAnimationCallback(new Animatable2.AnimationCallback() {
@Override
public void onAnimationEnd(Drawable drawable) {
super.onAnimationEnd(drawable);
HeartBeat.this.removeAllViews();
HeartBeat.this.addTextView(context);
}
});
}
((AnimatedVectorDrawable) drawable).start();
}
}
public void setText(String text) {
this.mText = text;
}
private void addTextView(Context context) {
Animation animation = AnimationUtils.loadAnimation(context, R.anim.chat_message);
animation.reset();
setAnimation(animation);
TextView heartBeat = new TextView(context);
heartBeat.setText(mText);
heartBeat.setBackgroundResource(R.drawable.bg_chat_message);
heartBeat.setAnimation(animation);
HeartBeat.this.addView(heartBeat);
}
}