androidandroid-recyclerviewandroid-viewholdermultiview

Using multiple viewholders for several laytous


I'm an average programmer, and I'm trying to finalize a project, but I crashed again on an issue that is making me sleepy. The point is that i am trying to use several layouts in a recycleview, taking the data from firebase, in this case i will use several viewholders, but i did several tests with content that i searched, but some errors occur and i couldn't solve it. Can someone help me? I'll put all the code here, point out the errors, and if there is a simpler way to do this, you can talk. In the future I will reuse the code for another part of the application with more than 10 views.

Firebase.

enter image description here

Main.class

package com.example.visualizarautomoveis;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.content.Context;
import android.os.Bundle;
import android.widget.Toast;

import com.example.visualizarautomoveis.Adapatadores.AdaptadorGeral;
import com.example.visualizarautomoveis.Models.ModelBicicleta;
import com.example.visualizarautomoveis.Models.ModelCompleto;
import com.example.visualizarautomoveis.Models.ModelMoto;
import com.example.visualizarautomoveis.ViewHolderes.ViewHolderBicicletas;
import com.example.visualizarautomoveis.ViewHolderes.ViewHolderMotos;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;

import java.util.ArrayList;
import java.util.Collections;

public class MainActivity extends AppCompatActivity {

    private final String ested = "GE";
    private final String city = "Geoneion";

    DatabaseReference automoveis_banco;

    FirebaseDatabase database;

    ArrayList<ModelCompleto> list;

    private Context context;

    private RecyclerView recyclerView;

    RecyclerView.LayoutManager manager;
    AdaptadorGeral adaptadorGeral;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        recyclerView = findViewById(R.id.recyclerview);

        list = new ArrayList<ModelCompleto>();

        manager = new LinearLayoutManager(context);
        recyclerView.setLayoutManager(manager);

        automoveis_banco = FirebaseDatabase.getInstance().getReference().child(estet).child(cidy).child("Automoveis");

        automoveis_banco.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                for (DataSnapshot eventSnapshot: dataSnapshot.getChildren())
                {
                    ModelCompleto mod =eventSnapshot.getValue(ModelCompleto.class);
                    list.add(mod);

                    Collections.reverse(list);
                }
                adaptadorGeral = new AdaptadorGeral(MainActivity.this,list);
                recyclerView.setAdapter(adaptadorGeral);
                adaptadorGeral.notifyDataSetChanged();

            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });
    }
}

AdaptadorGeral.class

package com.example.visualizarautomoveis.Adapatadores;

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.example.visualizarautomoveis.Models.ModelCompleto;
import com.example.visualizarautomoveis.R;
import com.example.visualizarautomoveis.ViewHolderes.ViewHolderBicicletas;
import com.example.visualizarautomoveis.ViewHolderes.ViewHolderMotos;

import java.util.ArrayList;

public class AdaptadorGeral extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private final Context context;
    private final ArrayList<ModelCompleto> completos;

    private final String BICICLETA = "0";
    private final String MOTO = "1";

    public AdaptadorGeral(Context context, ArrayList<ModelCompleto> completos) 
    {
        this.context = context;
        this.completos = completos;

    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

        switch (completos.get(viewType).getTipo()){
            case "0":
                return new ViewHolderBicicletas(LayoutInflater.from(context).inflate(R.layout.popup_automoveis_bicicletas,parent,false));

            case "1":
                return new ViewHolderMotos(LayoutInflater.from(context).inflate(R.layout.popup_automoveis_motocicletas, parent, false));

            default:
                break;
        }
        return null;
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {

        switch (completos.get(position).getTipo()){

            case "0":
                RequestOptions requestOptions1 = new RequestOptions().placeholder(R.drawable.ic_launcher_background);
                ViewHolderBicicletas viewHolderBicicletas = (ViewHolderBicicletas) holder;

                ((ViewHolderBicicletas) holder).textViewMarca.setText(completos.get(position).getMarca());
                ((ViewHolderBicicletas) holder).textViewAno.setText(completos.get(position).getAno());
                ((ViewHolderBicicletas) holder).textViewDescrip.setText(completos.get(position).getDescricao());
                ((ViewHolderBicicletas) holder).textViewDataPublicacao.setText(completos.get(position).getDatapubicacao());
                ((ViewHolderBicicletas) holder).textViewValor.setText("R$ "+completos.get(position).getValor());
                Glide.with(context).load(completos.get(position).getFoto1()).apply(requestOptions1).into(((ViewHolderBicicletas) holder).imageViewFoto);
            case "1":
                RequestOptions requestOptions2 = new RequestOptions().placeholder(R.drawable.ic_launcher_background);
                ViewHolderMotos viewHolderMotos = (ViewHolderMotos)holder;

                ((ViewHolderMotos) holder).textViewMarca.setText(completos.get(position).getMarca());
                ((ViewHolderMotos) holder).textViewModelo.setText(completos.get(position).getModelo());
                ((ViewHolderMotos) holder).textViewAno.setText(completos.get(position).getAno());
                ((ViewHolderMotos) holder).textViewDescrip.setText(completos.get(position).getDescricao());
                ((ViewHolderMotos) holder).textViewDataPublicacao.setText(completos.get(position).getDatapubicacao());
                ((ViewHolderMotos) holder).textViewValor.setText("R$ "+completos.get(position).getValor());

                Glide.with(context).load(completos.get(position).getFoto1()).apply(requestOptions2).into(((ViewHolderMotos) holder).imageViewFoto);

        }
    }

    @Override
    public int getItemCount() {

        if (completos != null){
            return this.completos.size();
        }else {
            return 0;
        }
    }

    @Override
    public int getItemViewType(int position) {

        if (completos.get(position).getTipo().equals("0"))
            return 0;
        if (completos.get(position).getTipo().equals("1")) {
            return 1;
        }
        return position;
    }
}

ViewHolderBicicletas.class

package com.example.visualizarautomoveis.ViewHolderes;

import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.example.visualizarautomoveis.R;

public class ViewHolderBicicletas extends RecyclerView.ViewHolder{

    public  TextView textViewMarca;
    public  TextView textViewAno;
    public  TextView textViewDescrip;
    public  TextView textViewDataPublicacao;
    public  TextView textViewValor;
    public  ImageView imageViewFoto;

    public ViewHolderBicicletas(@NonNull View itemView) {
        super(itemView);

        textViewAno = itemView.findViewById(R.id.popup_ano_bicicleta);
        textViewMarca = itemView.findViewById(R.id.popup_marca_bicicleta);
        textViewDescrip = itemView.findViewById(R.id.popup_descricao_bicicleta);
        textViewDataPublicacao = itemView.findViewById(R.id.popup_data_pubicacao_bicicleta);
        imageViewFoto = itemView.findViewById(R.id.popup_imagem_central_bicicletas);
        textViewValor = itemView.findViewById(R.id.popup_valor_bicicleta);
    }
}

ViewHolderMotos.class

package com.example.visualizarautomoveis.ViewHolderes;

import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.example.visualizarautomoveis.R;

public class ViewHolderMotos extends RecyclerView.ViewHolder{

    public  TextView textViewMarca;
    public  TextView textViewModelo;
    public  TextView textViewAno;
    public  TextView textViewDescrip;
    public  TextView textViewDataPublicacao;
    public  TextView textViewValor;
    public  ImageView imageViewFoto;

    public ViewHolderMotos(@NonNull View itemView) {
        super(itemView);
        textViewAno = itemView.findViewById(R.id.popup_ano_motocicleta);
        textViewMarca = itemView.findViewById(R.id.popup_marca_motocicleta);
        textViewModelo = itemView.findViewById(R.id.popup_modelo_motocicleta);
        textViewDescrip = itemView.findViewById(R.id.popup_descricao_motocicleta);
        textViewDataPublicacao = itemView.findViewById(R.id.popup_data_public_moto);
        textViewValor = itemView.findViewById(R.id.popup_valor_motocicleta);

        imageViewFoto = itemView.findViewById(R.id.popup_imagem_central_motocicletas);

    }
}

ModelCompleto.class

package com.example.visualizarautomoveis.Models;

public class ModelCompleto {
    private String valor,descricao,datapubicacao,foto1,marca,ano,modelo,tipo;


    public ModelCompleto() {
    }

    public ModelCompleto(String valor, String descricao, String datapubicacao, String foto1, String marca, String ano, String modelo, String tipo) {
        this.valor = valor;
        this.descricao = descricao;
        this.datapubicacao = datapubicacao;
        this.foto1 = foto1;
        this.marca = marca;
        this.ano = ano;
        this.modelo = modelo;
        this.tipo = tipo;
    }

    public String getValor() {
        return valor;
    }

    public void setValor(String valor) {
        this.valor = valor;
    }

    public String getDescricao() {
        return descricao;
    }

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

    public String getDatapubicacao() {
        return datapubicacao;
    }

    public void setDatapubicacao(String datapubicacao) {
        this.datapubicacao = datapubicacao;
    }

    public String getFoto1() {
        return foto1;
    }

    public void setFoto1(String foto1) {
        this.foto1 = foto1;
    }

    public String getMarca() {
        return marca;
    }

    public void setMarca(String marca) {
        this.marca = marca;
    }

    public String getAno() {
        return ano;
    }

    public void setAno(String ano) {
        this.ano = ano;
    }

    public String getModelo() {
        return modelo;
    }

    public void setModelo(String modelo) {
        this.modelo = modelo;
    }

    public String getTipo() {
        return tipo;
    }

    public void setTipo(String tipo) {
        this.tipo = tipo;
    }
}

Error that appears when running the program:

D/TextView: setTypeface with style : 0
W/Glide: Failed to find GeneratedAppGlideModule. You should include an annotationProcessor compile dependency on com.github.bumptech.glide:compiler in your application and a @GlideModule annotated AppGlideModule implementation or LibraryGlideModules will be silently ignored
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.visualizarautomoveis, PID: 27653
    java.lang.ClassCastException: com.example.visualizarautomoveis.ViewHolderes.ViewHolderBicicletas cannot be cast to com.example.visualizarautomoveis.ViewHolderes.ViewHolderMotos
        at com.example.visualizarautomoveis.Adapatadores.AdaptadorGeral.onBindViewHolder(AdaptadorGeral.java:84)
        at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:7065)
        at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:7107)
        at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:6012)
        at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6279)
        at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6118)
        at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6114)
        at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2303)
        at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1627)
        at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1587)
        at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:665)
        at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:4134)
        at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:3851)
        at androidx.recyclerview.widget.RecyclerView.onLayout(RecyclerView.java:4404)
        at android.view.View.layout(View.java:18010)
        at android.view.ViewGroup.layout(ViewGroup.java:5911)
        at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1080)
        at android.view.View.layout(View.java:18010)
        at android.view.ViewGroup.layout(ViewGroup.java:5911)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:344)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:281)
        at android.view.View.layout(View.java:18010)
        at android.view.ViewGroup.layout(ViewGroup.java:5911)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1742)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1585)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1494)
        at android.view.View.layout(View.java:18010)
        at android.view.ViewGroup.layout(ViewGroup.java:5911)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:344)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:281)
        at android.view.View.layout(View.java:18010)
        at android.view.ViewGroup.layout(ViewGroup.java:5911)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1742)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1585)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1494)
        at android.view.View.layout(View.java:18010)
        at android.view.ViewGroup.layout(ViewGroup.java:5911)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:344)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:281)
        at com.android.internal.policy.PhoneWindow$DecorView.onLayout(PhoneWindow.java:3175)
        at android.view.View.layout(View.java:18010)
        at android.view.ViewGroup.layout(ViewGroup.java:5911)
        at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2776)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2477)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1544)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7602)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
        at android.view.Choreographer.doCallbacks(Choreographer.java:686)
        at android.view.Choreographer.doFrame(Choreographer.java:622)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:148)
        at android.app.ActivityThread.main(ActivityThread.java:7331)
Process 27653 terminated.

Solution

  • Here logcat is clearly saying that - classCastException. So, Use the break statement for switch. Because you didn't added break statement - every time it is creating the ViewHolderMotos instance.

      @Override
            public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
    
                switch (completos.get(position).getTipo()){
    
                    case "0":
                        RequestOptions requestOptions1 = new RequestOptions().placeholder(R.drawable.ic_launcher_background);
                        ViewHolderBicicletas viewHolderBicicletas = (ViewHolderBicicletas) holder;
    
                        ((ViewHolderBicicletas) holder).textViewMarca.setText(completos.get(position).getMarca());
                        ((ViewHolderBicicletas) holder).textViewAno.setText(completos.get(position).getAno());
                        ((ViewHolderBicicletas) holder).textViewDescrip.setText(completos.get(position).getDescricao());
                        ((ViewHolderBicicletas) holder).textViewDataPublicacao.setText(completos.get(position).getDatapubicacao());
                        ((ViewHolderBicicletas) holder).textViewValor.setText("R$ "+completos.get(position).getValor());
                        Glide.with(context).load(completos.get(position).getFoto1()).apply(requestOptions1).into(((ViewHolderBicicletas) holder).imageViewFoto);
    
                    break;
                    case "1":
                        RequestOptions requestOptions2 = new RequestOptions().placeholder(R.drawable.ic_launcher_background);
                        ViewHolderMotos viewHolderMotos = (ViewHolderMotos)holder;
    
                        ((ViewHolderMotos) holder).textViewMarca.setText(completos.get(position).getMarca());
                        ((ViewHolderMotos) holder).textViewModelo.setText(completos.get(position).getModelo());
                        ((ViewHolderMotos) holder).textViewAno.setText(completos.get(position).getAno());
                        ((ViewHolderMotos) holder).textViewDescrip.setText(completos.get(position).getDescricao());
                        ((ViewHolderMotos) holder).textViewDataPublicacao.setText(completos.get(position).getDatapubicacao());
                        ((ViewHolderMotos) holder).textViewValor.setText("R$ "+completos.get(position).getValor());
    
                        Glide.with(context).load(completos.get(position).getFoto1()).apply(requestOptions2).into(((ViewHolderMotos) holder).imageViewFoto);
    
                    break;
    
                }
            }