0

On RecyclerView data is not showing.

I have tried hard but i am unable to get the solution even i have search lot of questions on StackoverFlow and on other platforms as well. I want to do like below attached image:

preview_image

Here's the code:

activity_data_sekretaris.xml

    <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Sekretaris.DataSekretarisActivity"
    android:background="@color/colorPrimary">

    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/swipe_refresh"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <android.support.v7.widget.RecyclerView
            android:id="@+id/rc_data"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
        </android.support.v7.widget.RecyclerView>
    </android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>

SekretarisAdapter.java

package tgs.app.absensi;

import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.List;

import tgs.app.absensi.model.Sekretaris;

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

private List<Sekretaris.Siswa> dataSiswa;
private List<Sekretaris.Kelas> dataKelas;

public SekretarisAdapter(List<Sekretaris.Siswa> dataSiswa, List<Sekretaris.Kelas> dataKelas) {
    this.dataSiswa = dataSiswa;
    this.dataKelas = dataKelas;
}

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

@Override
public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) {
    viewHolder.text_no.setText(dataSiswa.get(i).getId_siswa());
    viewHolder.text_nis.setText(dataSiswa.get(i).getNIS());
    viewHolder.text_nama.setText(dataSiswa.get(i).getNama_lengkap());
    viewHolder.text_jenisk.setText(dataSiswa.get(i).getJenis_kelamin());
    viewHolder.text_kelas.setText(dataKelas.get(i).getNama_kelas());
    viewHolder.text_jurusan.setText(null);
    viewHolder.text_status.setText(dataSiswa.get(i).getStatus());
}

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

public class ViewHolder extends RecyclerView.ViewHolder {
    TextView text_no, text_nis, text_nama, text_jenisk, text_kelas, text_jurusan, text_status;

    public ViewHolder(@NonNull View itemView) {
        super(itemView);
        text_no = itemView.findViewById(R.id.text_no);
        text_nis = itemView.findViewById(R.id.text_nis);
        text_nama = itemView.findViewById(R.id.text_nama);
        text_jenisk = itemView.findViewById(R.id.text_jenisKelamin);
        text_kelas = itemView.findViewById(R.id.text_kelas);
        text_jurusan = itemView.findViewById(R.id.text_jurusan);
        text_status = itemView.findViewById(R.id.text_status);
    }
}

}

DataSekretarisActivity.java

package tgs.app.absensi.Sekretaris;

import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;

import java.util.List;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import tgs.app.absensi.R;
import tgs.app.absensi.SekretarisAdapter;
import tgs.app.absensi.model.Sekretaris;
import tgs.app.absensi.retrofit.Api;
import tgs.app.absensi.retrofit.ApiInterface;

public class DataSekretarisActivity extends AppCompatActivity {

SwipeRefreshLayout swipe_refresh;
RecyclerView recyclerView;

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

    swipe_refresh = findViewById(R.id.swipe_refresh);
    recyclerView = findViewById(R.id.rc_data);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    recyclerView.setHasFixedSize(true);

    DataSekretaris();
    swipe_refresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            swipe_refresh.setRefreshing(true);
            DataSekretaris();
        }
    });


    getSupportActionBar().setTitle("Data Absen Siswa");
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}

private void DataSekretaris(){
    ApiInterface apiInterface = Api.getUrl().create(ApiInterface.class);
    Call<Sekretaris> call = apiInterface.getSekretarisCall();
    call.enqueue(new Callback<Sekretaris>() {
        @Override
        public void onResponse(Call<Sekretaris> call, Response<Sekretaris> response) {
            swipe_refresh.setRefreshing(false);
            List<Sekretaris.Siswa> detailSiswa = response.body().getReadSiswa();
            List<Sekretaris.Kelas> detailKelas = response.body().getReadKelas();
            recyclerView.setAdapter(new SekretarisAdapter(detailSiswa, detailKelas));
        }

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

        }
    });
}

@Override
public boolean onSupportNavigateUp() {
    finish();
    return super.onSupportNavigateUp();
}

}

could anyone fix my error? Thanks in advance.

singh.indolia
  • 1,292
  • 13
  • 26
  • Try setting up an empty adapter first, update it when you can. ([Original answer](https://stackoverflow.com/questions/29141729/recyclerview-no-adapter-attached-skipping-layout#comment49234469_30581896)) – Andrés R.C. Feb 21 '19 at 01:33

2 Answers2

0

You should first setup the RecyclerView correctly, like @AndrésR.C. says, by using a default adapter.

So, initialize your RecyclerView with something like this:

private RecyclerView mRvSekretaris;
private SekretarisAdapter mSkretarisAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...

    mRvSekretaris = findViewById(R.id.rc_data);
    mRvSekretaris.setLayoutManager(new LinearLayoutManager(this));

    // initialize list with empty item
    List<Sekretaris.Siswa> detailSiswa = new ArrayList<>();
    List<Sekretaris.Kelas> detailKelas = new ArrayList<>();
    mSkretarisAdapter = new SekretarisAdapter(detailSiswa, detailKelas);

    mRvSekretaris.setAdapter(mSkretarisAdapter);

then when you want to refresh the list, you just need to swap the items adapter with swap method in your adapter:

mSkretarisAdapter.swap(detailSiswa, detailKelas);

with the following swap method:

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

    private List<Sekretaris.Siswa> dataSiswa;
    private List<Sekretaris.Kelas> dataKelas;

    ...

    public swap(List<Sekretaris.Siswa> dataSiswa, List<Sekretaris.Kelas> dataKelas) {

      this.dataSiswa = dataSiswa;
      this.dataKelas = dataKelas;
      notifyDataSetChanged();
    }
}

Please take note that you should not swapping all the items instead you need to use something like DiffUtil

ישו אוהב אותך
  • 28,609
  • 11
  • 78
  • 96
0

You can set adapter before making network call and passing empty lists,and making both list objects global

// initialize list with empty item
 detailSiswa = new ArrayList<>();
 detailKelas = new ArrayList<>()
mRvSekretaris.setLayoutManager(new LinearLayoutManager(this));
mSkretarisAdapter = new SekretarisAdapter(detailSiswa, detailKelas);
mRvSekretaris.setAdapter(mSkretarisAdapter);

And when you want to refresh the list, just call the refreshLists(dataSiswa,dataKelas);

private void refreshLists(ArrayListList<Sekretaris.Siswa> dataSiswa, ArrayListList<Sekretaris.Kelas> dataKelas){
    detailSiswa.clear();
    detailKelas.clear();
    if(dataSiswa.size>0 && dataKelas.size>0){
       detailSiswa.add(dataSiswa);
       detailKelas.add(dataKelas);
    }
    mSkretarisAdapter.notifyDataSetChanged();
}

Also, while setting data from lists in BindViewHolder, make sure that size of dataKelas should be equal to or greater than dataSiswa as because BindViewHolder will be called as many number of times as is the size of dataSiswa because of

public int getItemCount() {
return dataSiswa.size();

}

So, when you are accessing any field from dataKelas, it can thrown null pointer exception if size of dataKelas is smaller than that of dataSiswa.