Search code examples
androidretrofitadapter

Getting "No adapter attached; skipping layout" error when parsing a named JSON inside another list


I want to parse some JSON (Car models):

{"modelos": [{"nome": AMAROK},{"nome": JETTA}]}

I have the code below: ADAPTER

public class ListaVeiculosAdapter extends RecyclerView.Adapter<ListaVeiculosAdapter.ListaVeiculosViewHolder> {

private List<VeiculosResponse> veiculos;

public ListaVeiculosAdapter(List<VeiculosResponse> veiculos) {
    this.veiculos = veiculos;
}

public ListaVeiculosAdapter() {

}

@NonNull
@Override
public ListaVeiculosViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_veiculo, parent, false);

    return new ListaVeiculosViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull ListaVeiculosViewHolder holder, int position) {
    holder.textNomeVeiculo.setText(veiculos.get(position).getNome());
}

@Override
public int getItemCount() {
    return (veiculos!= null && veiculos.size()>0) ? veiculos.size() : 0;
}

static class ListaVeiculosViewHolder extends RecyclerView.ViewHolder{

    private TextView textNomeVeiculo;

    public ListaVeiculosViewHolder(View itemView){
        super(itemView);

        textNomeVeiculo = itemView.findViewById(R.id.text_veiculo);
    }

}}

Main Activity:

RecyclerView recyclerVeiculos;

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

    // Toolbar toolbar = findViewById(R.id.my_toolbar);
    //setSupportActionBar(toolbar);

    recyclerVeiculos = findViewById(R.id.my_recycler_view);

    ListaVeiculosAdapter adapter = new ListaVeiculosAdapter();
    ApiService.getInstance().getModels().enqueue(new Callback<VeiculosResult>() {
        @Override
        public void onResponse(Call<VeiculosResult> call, Response<VeiculosResult> response) {
            RecyclerView.LayoutManager linearLayoutManager = new LinearLayoutManager(ListaVeiculosActivity.this);
            recyclerVeiculos.setLayoutManager(linearLayoutManager);
            recyclerVeiculos.setAdapter(new ListaVeiculosAdapter(response.body().getModelos()));

        }

        @Override
        public void onFailure(Call<VeiculosResult> call, Throwable t) {

        }
    });


}}

The problem is that I get the error

"E/RecyclerView: No adapter attached; skipping layout"

when I try to run the application.

Other Retrofit configuration codes:

public interface VeiculosService {
    @GET("marcas/59/modelos")
    Call<VeiculosResult> getModels();
}


    private static VeiculosService INSTANCE;

public static VeiculosService getInstance() {
    if(INSTANCE == null){
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("https://parallelum.com.br/fipe/api/v1/carros/")
            .addConverterFactory(MoshiConverterFactory.create())
            .build();

        INSTANCE = retrofit.create(VeiculosService.class);
     }
    return INSTANCE;
}

My idea is to create a list (recycler view) with car models so the user can choose which car they want.


Solution

  • You have to set layout manager and set adapter to your recyclerview before API call.

    Modify your MainActivity like this.

    
     RecyclerView recyclerVeiculos;
     List<VeiculosResponse> veiculos;
     ListaVeiculosAdapter adapter;
    
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_lista_veiculos);
    
        // Toolbar toolbar = findViewById(R.id.my_toolbar);
        //setSupportActionBar(toolbar);
    
        recyclerVeiculos = findViewById(R.id.my_recycler_view);
    
        RecyclerView.LayoutManager linearLayoutManager = new 
        LinearLayoutManager(ListaVeiculosActivity.this);
        recyclerVeiculos.setLayoutManager(linearLayoutManager);
    
        // create an empty list and pass it to your adapter
        veiculos = new ArrayList<>()
        adapter = new ListaVeiculosAdapter(veiculos)
        recyclerVeiculos.setAdapter(adapter);
    
        ApiService.getInstance().getModels().enqueue(new Callback<VeiculosResult>() {
            @Override
            public void onResponse(Call<VeiculosResult> call, Response<VeiculosResult> response) {
               if (response.isSuccessful() && response.body() != null){
                    veiculos.addAll(response.body().getModelos());
                   // after getting new data you have to notify your adapter that your data set is changed like below.
                   adapter.notifyDataSetChanged();
               }
    
    
            }
    
            @Override
            public void onFailure(Call<VeiculosResult> call, Throwable t) {
    
            }
        });
    
    
    
    
    
    // ...