java - 具有动态部分的 RecyclerView

标签 java android android-studio android-recyclerview

我必须在 RecyclerView 中按部分列出来自 API 的消耗数据,以及我通过 API 获取的该部分的名称,但是应用程序在到达 时会关闭onBindViewHolder 但有异常(exception)

FATAL EXCEPTION: main Process: [package], PID: 25882 java.lang.IndexOutOfBoundsException: Index: 3, Size: 2 at java.util.ArrayList.get(ArrayList.java:437)

at NewPatrimonio.Adapter.PatrimonioReferenciaAdapter.onBindViewHolder(PatrimonioReferenciaAdapter.java:32)

Like this

MyJson:

[
    {
        "familia": "ATENDIMENTO",
        "patrimonios": [
            {
                "descricao": "PORTEIRO",
                "controle": "68D60C5DFFF27C6D7B6E6D2BF7C9E8B0",
                "quantidade": 0
            },
            {
                "descricao": "RECEPCIONISTA",
                "controle": "CBC9D1C219BAF179310A2C9A5AE94921",
                "quantidade": 0
            }
        ]
    },
    {
        "familia": "COLABORADORES",
        "patrimonios": [
            {
                "descricao": "EQUIPE DE ADMINISTRAÇÃO",
                "controle": "ADAD1F3A829F53387354E97FE3DD9026",
                "quantidade": 1
            },
            {
                "descricao": "EQUIPE DE ATENDIMENTO",
                "controle": "959BCCAEE13EB0E9A62AB7231077B0F2",
                "quantidade": 0
            },
            {
                "descricao": "EQUIPE DE JARDINAGEM",
                "controle": "798ABCFCA7ECFD727B751CC42C1E3E77",
                "quantidade": 0
            },
            {
                "descricao": "EQUIPE DE LIMPEZA",
                "controle": "3E2F32AB45C9EC327DD4A105BB838FC9",
                "quantidade": 0
            }
        ]
    },
    {
        "familia": "GERAL",
        "patrimonios": [
            {
                "descricao": "AJUDANTE",
                "controle": "11F08FC1F04E361F661DC76820AAABB7",
                "quantidade": 1
            },
            {
                "descricao": "FISCAL",
                "controle": "EEFC72871E5201D5752F12BF97B8368B",
                "quantidade": 0
            }
        ]
    },
    {
        "familia": "LIMPEZA",
        "patrimonios": [
            {
                "descricao": "FAXINEIRO",
                "controle": "A84EB5A2B0B25FCA905DC6DDC07B9598",
                "quantidade": 0
            }
        ]
    }
]

我的模型:

public class ModelNovoReferencia {

    @SerializedName("familia")
    @Expose
    private String familia;
    @SerializedName("patrimonios")
    @Expose
    private List<Patrimonio> patrimonios = null;

    public String getFamilia() {
        return familia;
    }

    public void setFamilia(String familia) {
        this.familia = familia;
    }

    public List<Patrimonio> getPatrimonios() {
        return patrimonios;
    }

    public void setPatrimonios(List<Patrimonio> patrimonios) {
        this.patrimonios = patrimonios;
    }

    public class Patrimonio {

        @SerializedName("descricao")
        @Expose
        private String descricao;
        @SerializedName("controle")
        @Expose
        private String controle;
        @SerializedName("quantidade")
        @Expose
        private Integer quantidade;

        public String getDescricao() {
            return descricao;
        }

        public void setDescricao(String descricao) {
            this.descricao = descricao;
        }

        public String getControle() {
            return controle;
        }

        public void setControle(String controle) {
            this.controle = controle;
        }

        public Integer getQuantidade() {
            return quantidade;
        }

        public void setQuantidade(Integer quantidade) {
            this.quantidade = quantidade;
        }
    }
}

我的适配器:

public class PatrimonioReferenciaAdapter extends RecyclerView.Adapter<PatrimonioReferenciaAdapter.ReferenciaVH> {
    List<ModelNovoReferencia> mListaReferencia;
    ModelNovoReferencia.Patrimonio patrimonio;

    public PatrimonioReferenciaAdapter(List<ModelNovoReferencia> mDadosReferencia) {
        this.mListaReferencia = mDadosReferencia;
    }

    @Override
    public ReferenciaVH onCreateViewHolder(ViewGroup parent, int viewType) {

        View itemListaRelacao = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_novo_referencia, parent, false);
        return new ReferenciaVH(itemListaRelacao);
    }

    @Override
    public void onBindViewHolder(ReferenciaVH holder, int position) {
        holder.txtFamilia.setText(mListaReferencia.get(position).getFamilia());
        holder.txtDescricao.setText(mListaReferencia.get(position).getPatrimonios().get(position).getDescricao());
    }

    @Override
    public int getItemCount() {
        return mListaReferencia.size();
    }

    public class ReferenciaVH extends RecyclerView.ViewHolder {
        TextView txtFamilia, txtDescricao, txtQuantidade;

        public ReferenciaVH(View itemView) {
            super(itemView);
            txtFamilia = (TextView) itemView.findViewById(R.id.txtFamilia);
            txtDescricao = (TextView) itemView.findViewById(R.id.txtDescricaoRef);
            txtQuantidade = (TextView) itemView.findViewById(R.id.txtQtdRef);
        }
    }
}

MyRow:

<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/txtFamilia"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:text="Sem família"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <android.support.v7.widget.CardView
        android:layout_width="0dp"
        android:layout_height="70dp"
        android:layout_marginBottom="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="3dp"
        app:cardElevation="4dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/txtFamilia">

        <android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <TextView
                android:id="@+id/txtDescricaoRef"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginEnd="8dp"
                android:layout_marginStart="8dp"
                android:layout_marginTop="8dp"
                android:text="TextView"
                android:textAlignment="center"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <TextView
                android:id="@+id/txtQtdRef"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="8dp"
                android:layout_marginStart="8dp"
                android:layout_marginTop="8dp"
                android:text="Quantidade já cadastrados"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/txtDescricaoRef" />
        </android.support.constraint.ConstraintLayout>
    </android.support.v7.widget.CardView>
</android.support.constraint.ConstraintLayout>

我做错了什么或者正确的实现是什么?

最佳答案

问题出在这一行:

holder.txtDescricao.setText(mListaReferencia.get(position).getPatrimonios().get(position).getDescricao());

具体来说,问题出在双重 get() 调用中:

mListaReferencia.get(position).getPatrimonios().get(position)

onBindViewHolder()position 参数只能用于索引 mListaReferencia,而不能用于索引patrimonios 子列表。您如何解决这个问题将取决于您想要的最终行为。

看来您真正想要的实际上相当复杂(一个 RecyclerView 使用两种不同的 View 类型,一种用于显示 ModelNovoReferencia.familia ,另一种用于显示 Patrimonio信息)。我不会在这里提供有关如何执行此操作的完整教程;只需搜索“RecyclerView 多种 View 类型”即可。

目前,您可以通过将 onBindViewHolder() 更改为如下内容来解决该问题:

@Override
public void onBindViewHolder(ReferenciaVH holder, int position) {
    holder.txtFamilia.setText(mListaReferencia.get(position).getFamilia());
    holder.txtDescricao.setText("" + mListaReferencia.get(position).getPatrimonios().size());
}

关于java - 具有动态部分的 RecyclerView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51661141/

相关文章:

java - 如何在 sqlldr ctl 文件中设置主键?

java - Sublime Text 无法识别 NumberFormat

java - Catch 中的语句未执行

android-studio - 我有 Android Studio 1.0,我可以安全地删除 .AndroidStudioBeta 文件夹吗?

android - 在 onclick recyclerview 中 toast

java - 如何从iso时间中减去1分钟

java - Android GPS 需要一段时间才能准确

android - dlopen 失败 : cannot locate symbol "__cxa_finalize" referenced by "/system/lib/libdl.so"

php 文件返回错误转换为 Android GET 请求的 JSON

android-studio - 在多个 Gradle 脚本中重用 def 定义