【问题标题】:RecyclerView with dynamic sections具有动态部分的 RecyclerView
【发布时间】:2018-08-02 19:48:19
【问题描述】:

我必须在RecyclerView 中按部分列出来自 API 的消费数据,以及我通过 API 获得的该部分的名称,但是应用程序在到达 onBindViewHolder 时会关闭,但例外情况

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>

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

【问题讨论】:

  • 我认为错误是由.getPatrimonios().get(position) 引起的,我需要更多信息来帮助。
  • 问题很可能出在这里,getPatrimonios().get(position).getDescricao()),你怎么知道列表和适配器大小一样?使用日志获取子大小或使用第一个位置
  • 我编辑了我的问题并添加了我从 API 获得的 Json 返回。我也相信错误在你说的这一行,但是我如何获得孩子的位置?

标签: java android android-studio android-recyclerview


【解决方案1】:

问题出在这一行:

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

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

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

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

您真正想要的似乎很复杂(RecyclerView 使用两种不同的视图类型,一种显示ModelNovoReferencia.familia,另一种显示Patrimonio 信息)。我不会在这里给出如何做到这一点的完整教程;只需搜索“RecyclerView 多种视图类型”即可。

现在,您可以通过将 onBindViewHolder() 更改为以下内容来解决此问题:

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

【讨论】:

  • 我进行了更改,但它给了我另一个错误。但它对我的研究建议帮助很大,我不知道。谢谢!
  • @MRah FATAL EXCEPTION: main Process: PID: 29962 android.content.res.Resources$NotFoundException: String resource ID #0x2 at android.content.res.Resources.getText(Resources.java:338)
  • 那是因为无法获取您尝试从中获取文本的资源,请更新完整的错误日志
  • @JonasVieira 确保在我发布的setText() 调用中包含空字符串(例如,它应该是setText("" + ...))。如果你不这样做,android 会认为你引用的是字符串资源,而不是仅仅试图显示恰好是数字的文本。
猜你喜欢
  • 2020-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-06
  • 2018-09-06
相关资源
最近更新 更多