Jean Pierre Jordan
Jean Pierre Jordan

Reputation: 33

Troubles using fragment with RecyclerView and Retrofit

I have this error, actually I don't know about fragments.

CreatView

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_inicio, container,
                false);
        getActivity().setTitle(R.string.inicio);
        recyclerView = (RecyclerView) rootView.findViewById(R.id.card_recycler_view);
        recyclerView.setHasFixedSize(true);
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity());
        recyclerView.setLayoutManager(layoutManager);
        loadJSON();
        return rootView;
    }

loadJSON void

private void loadJSON(){
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("http://192.168.1.42:3000/")
            .addConverterFactory(GsonConverterFactory.create())
            .build();
    RequestInterface request = retrofit.create(RequestInterface.class);
    Call<JSONResponse> call = request.getJSON();
    call.enqueue(new Callback<JSONResponse>() {
        @Override
        public void onResponse(Call<JSONResponse> call, Response<JSONResponse> response) {
            JSONResponse jsonResponse = response.body();
            data = new ArrayList<>(Arrays.asList(jsonResponse.getCupon()));
            adapter = new CuponAdapter(data);
            recyclerView.setAdapter(adapter);
        }

        @Override
        public void onFailure(Call<JSONResponse> call, Throwable t) {
            Log.d("Error", t.getMessage());
        }
    });
}

Adapter

public class CuponAdapter extends RecyclerView.Adapter<CuponAdapter.ViewHolder> {
private ArrayList<Cupon> cupon;

public CuponAdapter(ArrayList<Cupon> cupon) {
    this.cupon = cupon;
}

@Override
public CuponAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
    View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.card_row, viewGroup, false);
    return new ViewHolder(view);
}

@Override
public void onBindViewHolder(ViewHolder holder, int i) {
    holder.tv_titulo.setText(cupon.get(i).getTitulo());
    holder.tv_empresa.setText(cupon.get(i).getEmpresa());
    holder.tv_descripcion.setText(cupon.get(i).getDescripcion());
}

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

public class ViewHolder extends RecyclerView.ViewHolder {
    private TextView tv_titulo, tv_descripcion, tv_empresa;

    public ViewHolder(View view) {
        super(view);
        tv_titulo = (TextView) view.findViewById(R.id.tv_titulo);
        tv_descripcion = (TextView) view.findViewById(R.id.tv_descripcion);
        tv_empresa = (TextView) view.findViewById(R.id.tv_empresa);
    }
}
}

The Error

12-08 00:00:05.727 1784-1784/com.mighty.cupoferta E/RecyclerView: No adapter attached; skipping layout

This code is based on this link . But he explains how to put in an activity, how can I put in a fragment?

Upvotes: 0

Views: 2737

Answers (3)

Paras Verma
Paras Verma

Reputation: 129

set your adapter in the onCreateView function and use .notifyDataSetChanged() in the loadJSON function to notifiy the adapter about the changes in the data like the code below.

public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_inicio, container,
            false);
    getActivity().setTitle(R.string.inicio);
    recyclerView = (RecyclerView) rootView.findViewById(R.id.card_recycler_view);
    recyclerView.setHasFixedSize(true);
    RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity());
    recyclerView.setLayoutManager(layoutManager);
    recyclerView.setAdapter(adapter);
    loadJSON();
    return rootView;
 }

and in your adapter class write this

private void loadJSON(){
Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("http://192.168.1.42:3000/")
        .addConverterFactory(GsonConverterFactory.create())
        .build();
RequestInterface request = retrofit.create(RequestInterface.class);
Call<JSONResponse> call = request.getJSON();
call.enqueue(new Callback<JSONResponse>() {
    @Override
    public void onResponse(Call<JSONResponse> call, Response<JSONResponse> response) {
        JSONResponse jsonResponse = response.body();
        data = new ArrayList<>(Arrays.asList(jsonResponse.getCupon()));
        adapter = new CuponAdapter(data);
        adapter.notifyDataSetChanged();
    }

    @Override
    public void onFailure(Call<JSONResponse> call, Throwable t) {
        Log.d("Error", t.getMessage());
    }
});
}

Upvotes: 0

Rajan Kali
Rajan Kali

Reputation: 12953

Well it is because you are setting adapter after delay, try to set an empty adapter to recyclerview before you return rootView, then update adapter on Retrofit callback as in

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_inicio, container,
                false);
        getActivity().setTitle(R.string.inicio);
        recyclerView = (RecyclerView) rootView.findViewById(R.id.card_recycler_view);
        recyclerView.setHasFixedSize(true);
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity());
        recyclerView.setLayoutManager(layoutManager);
        recyvlerView.setAdapter(new CuponAdapter(new ArrayList<Cupon>()));
        loadJSON();
        return rootView;
    }

Upvotes: 0

Sajal Gupta
Sajal Gupta

Reputation: 146

  call.enqueue(new Callback<JSONResponse>() {
    @Override
    public void onResponse(Call<JSONResponse> call, Response<JSONResponse> response) {
        JSONResponse jsonResponse = response.body();
        data = new ArrayList<>(Arrays.asList(jsonResponse.getCupon()));
        adapter = new CuponAdapter(data);
        recyclerView.setAdapter(adapter);
    }

Do not depend on network response to set your adapter.

RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);

You can do it right here.

Then after the network response you can add data to the adapter and call notifyDataSetChanged()

Upvotes: 1

Related Questions