奇怪的RecyclerView和ListView行为

时间:2018-02-10 18:16:51

标签: android android-recyclerview

首先抱歉我的英语不好。

我对RecyclerView有疑问。我的布局包含EditText,提交按钮和RecyclerView

我可以在EditText中输入一些文字,然后点击提交,文字就会添加到RecyclerView。问题是,如果有很多消息,那么RecyclerView会变得疯狂。它停止显示正确的消息,它与消息的顺序混淆等等。

如果我设置holder.setIsRecyclable(false);一切似乎都运行正常,但在我看来这是一个很差的解决方案。

对于单个项目的布局,我使用自定义LinearLayout视图,这可能会导致问题,但我不确定。

如何敲诈RecyclerView以保留添加项目的正确顺序?

这是我的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);
        }
    }
}

我发现我的自定义视图会产生问题。我可能以糟糕的方式过度工作。

这是我的自定义视图,它位于适配器中。

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);
}
}

1 个答案:

答案 0 :(得分:0)

我检查了您的代码后,您需要修改addItem类中的MessagesAdapter函数,如下所示。

void addItem(String message) {
    this.messagesList.add(message);
    notifyDataSetChanged();
}

这应该可以回收您的观点。