java - 尽管没有在任何地方清除,但构造函数中的 ArrayList 分配的数据正在丢失其数据

标签 java android android-recyclerview

我遇到了一个奇怪的问题。我有一个RecyclerAdapter它有两个构造函数。我使用同一个适配器来填充两个 RecyclerViews我想要看起来一样,但它们略有不同&它们位于两个不同的 fragment 中。因此有两个构造函数:

public FinderRecycleAdapter(Context context, ArrayList<String> data) {
    this.mInflater = LayoutInflater.from(context);
    this.mData = data;
    this.mContext = context;
    groupsHidden = new ArrayList<>();

}

public FinderRecycleAdapter(Context context, ArrayList<String> data, ArrayList<String> userEnteredWords) {
    this.mInflater = LayoutInflater.from(context);
    this.mData = data;
    this.mContext = context;
    this.userEnteredWords = userEnteredWords;
    groupsHidden = new ArrayList<>();
}

第二个是我遇到问题的地方。一切都显示并运行。 RecyclerView将显示单词列表。用户将输入其中一些单词 - 我想做的就是更改用户输入的列表中单词的颜色(这不是问题)。这些词被传递并分配给 ArrayList<string>已成功完成,如下所示:

enter image description here

但是,当涉及到更改这些单词的颜色时,请在 onBindViewHolder 中执行此操作此列表现在为空:

enter image description here

尽管没有在其他地方修改此列表。

这是该列表的所有用法。第 102-103 行是上图中的行,第 43 行是上面的构造函数代码。

enter image description here

奇怪的是this.mData (也是 ArrayList<string> )在任何地方都使用 this.userEnteredWords但是this.mData保留其值(value)。

这是全部onBindViewHolder代码,但我认为您需要在 onBindViewHolder 中看到大部分内容在第二张图片中。

 // binds the data to the TextView in each row
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    String word = mData.get(position);
    holder.wordRow.setText(word);

    if (holder.wordRow.getText().toString().matches((".*\\d.*"))) {
        int checkHeaderNum = Integer.parseInt(holder.wordRow.getText().toString().replaceAll("\\D+", ""));

        holder.wordRow.setBackgroundColor(this.mContext.getResources().getColor(R.color.colorPrimary));
        holder.wordRow.setTextColor(this.mContext.getResources().getColor(R.color.white));
        holder.wordRow.setTextSize(25);
        holder.wordRow.setBackground(ContextCompat.getDrawable(mContext, R.drawable.textview_rounded));
        if (this.groupsHidden.contains(checkHeaderNum)) {
            holder.wordRow.setCompoundDrawablesRelativeWithIntrinsicBounds(R.drawable.ic_maximize_white_24dp, 0, R.drawable.ic_maximize_white_24dp, 0); //Inserts the maximizes symbol to the end of TextRow
        } else {
            holder.wordRow.setCompoundDrawablesRelativeWithIntrinsicBounds(R.drawable.ic_minimize_white_24dp, 0, R.drawable.ic_minimize_white_24dp, 0); //Inserts the minimised symbol to the end of TextRow
        }
        holder.wordRow.setPadding(20, 0, 20, 0);

    } else {
        //Resets anything previously made as any attributes previously made will still hold unless reset here
        holder.wordRow.setBackgroundColor(this.mContext.getResources().getColor(R.color.white));
        holder.wordRow.setTextColor(this.mContext.getResources().getColor(R.color.browser_actions_text_color));
        holder.wordRow.setBackgroundResource(0);
        holder.wordRow.setTextSize(22);
        holder.wordRow.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, 0, 0);
        holder.wordRow.setPadding(20, 0, 20, 0);

        //Highlighting the letters the user has given if a condition was set -  only for home fragment
        if (isCondition()) {
            int startingIndex = word.indexOf(getUsersLetterEntry());
            int endingIndex = getUsersLetterEntry().length() + startingIndex;

            final SpannableStringBuilder str = new SpannableStringBuilder(word);
            str.setSpan(
                    new ForegroundColorSpan(ContextCompat.getColor(mContext, R.color.blue)), //Making selection colored
                    startingIndex,
                    endingIndex,
                    SpannableStringBuilder.SPAN_EXCLUSIVE_EXCLUSIVE
            );
            str.setSpan(new StyleSpan(Typeface.BOLD), startingIndex, endingIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); //Making selection bold
            holder.wordRow.setText(str);
        }


        //Setting the user entered words for the letter game to blue. This is only populated if has been called from the LettersGame fragment
        if (this.userEnteredWords != null && this.userEnteredWords.size() > 0) {
            if (this.userEnteredWords.contains(holder.wordRow.getText().toString())) {
                holder.wordRow.setTextColor(this.mContext.getResources().getColor(R.color.blue));
                holder.wordRow.setTypeface(Typeface.DEFAULT_BOLD);
            }
        }


    }

我错过了一些完全明显的东西吗?我以前没有遇到过这个。

最佳答案

你的构造函数不会复制数据,它只是保留传入的完全相同的ArrayList。因此,如果稍后修改了对象外部可用的ArrayList,则更改也将反射(reflect)在对象的ArrayList中,因为它们是同一个对象。

我建议创建一个新的ArrayList,然后使用Collections.addAll

关于java - 尽管没有在任何地方清除,但构造函数中的 ArrayList 分配的数据正在丢失其数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61417177/

相关文章:

java - http 多部分发布请求,包含 json 和带有 koush/ion 库的图像

java - 使用按钮将 arraylist 元素添加到文本字段

android - Gradle 任务从 Android Studio 失败,Wrapper 工作正常

构建期间的 Android 错误 - "default public constructor with no argument must be declared"。什么原因?

Android 管理 API 和 VpnService

android - 如何防止 RecyclerView 单元格的子元素在用户滚动时移动

java - 这是将 MVVM 结构与 ViewModel 和 RecyclerView 一起使用而没有任何问题的正确方法吗?

java - 将base64编码的字符串存储在HBase中

java - 异步读取消息时检查 JMS 类型

android - recyclerview 上方的 fragment 未显示