MVVM + Retrofit: retrieve JSON Object List then produces null

Deki Kurnia :

I'm learning to make an android application with MVVM, I found a problem that is the data from the API generates null values. I followed the tutorial from this link, but the data samples I take are different. the data I retrieve is an object and not an array I took the data from link

Model

    public class Corona {

    @SerializedName("Provinsi")
    private String provinsi;
    @SerializedName("Kasus_Posi")
    private String positif;
    @SerializedName("Kasus_Semb")
    private String sembuh;
    @SerializedName("Kasus_Meni")
    private String meninggal;

    public String getProvinsi() {
        return provinsi;
    }

    public void setProvinsi(String provinsi) {
        this.provinsi = provinsi;
    }

    public String getPositif() {
        return positif;
    }

    public void setPositif(String positif) {
        this.positif = positif;
    }

    public String getSembuh() {
        return sembuh;
    }

    public void setSembuh(String sembuh) {
        this.sembuh = sembuh;
    }

    public String getMeninggal() {
        return meninggal;
    }

    public void setMeninggal(String meninggal) {
        this.meninggal = meninggal;
    }

CoronaDataService

    public interface CoronaDataService {
         @GET("indonesia/provinsi")
         Call<List<Corona>> getCorona();
    }

**RetrofitClient**

    public class RetrofitClient {
    private static Retrofit retrofit;
    private static final String BASE_URL = "https://api.kawalcorona.com/";
    public static CoronaDataService getService() {
        if (retrofit == null) {
            retrofit = new Retrofit
                    .Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }
        return retrofit.create(CoronaDataService.class);
      }
    }

Repository

    public class CoronaRepository {
        private String TAG = "CoronaRepository";
        private MutableLiveData mutableLiveData = new MutableLiveData<>();

        public CoronaRepository() {
        }

        public MutableLiveData<List<Corona>> getMutableLiveData() {
            final CoronaDataService coronaDataService = RetrofitClient.getService();
            Call<List<Corona>> call = coronaDataService.getCorona();
            call.enqueue(new Callback<List<Corona>>() {

                @Override
                public void onResponse(Call<List<Corona>> call, Response<List<Corona>> response) {
                    Log.e(TAG, "onResponse: " + call.request().url());
                    Log.e(TAG, "onResponse: " + response.toString());
                    mutableLiveData.setValue(response.body());;
                }

                @Override
                public void onFailure(Call<List<Corona>> call, Throwable t) {
                    Log.e(TAG, "onResponse: " + call.request().url());
                    Log.e(TAG, "onFailure: " + t.getCause());
                    Log.e(TAG, "onFailure: " + t.getLocalizedMessage());
                    Log.e(TAG, "onFailure: " + t.getMessage());
                    Log.e(TAG, "onFailure: " + t.toString());
                }
            });
            return mutableLiveData;
        }
    }

Adapter

    public class CoronaDataAdapter extends RecyclerView.Adapter<CoronaDataAdapter.CoronaViewHolder> {
        private ArrayList<Corona> corona;

        @NonNull
        @Override
        public CoronaViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
            CoronaListItemBinding coronaListItemBinding =
                    DataBindingUtil.inflate(LayoutInflater.from(viewGroup.getContext()),
                            R.layout.corona_list_item, viewGroup, false);
            return new CoronaViewHolder(coronaListItemBinding);
        }

        @Override
        public void onBindViewHolder(@NonNull CoronaViewHolder coronaViewHolder, int i) {
            Corona c = corona.get(i);
            coronaViewHolder.coronaListItemBinding.setCorona(c);
        }

        @Override
        public int getItemCount() {
            if (corona != null) {
                return corona.size();
            } else {
                return 0;
            }
        }

        public void setCoronaList(ArrayList<Corona> corona) {
            this.corona = corona;
            notifyDataSetChanged();
        }

        static class CoronaViewHolder extends RecyclerView.ViewHolder {
            private CoronaListItemBinding coronaListItemBinding;

            CoronaViewHolder(@NonNull CoronaListItemBinding coronaListItemBinding) {
                super(coronaListItemBinding.getRoot());
                this.coronaListItemBinding = coronaListItemBinding;
            }
        }
    }

MainViewModel

    public class MainViewModel  extends AndroidViewModel {

        private CoronaRepository coronaRepository;
        public MainViewModel(@NonNull Application application) {
            super(application);
            coronaRepository = new CoronaRepository();
        }
        public LiveData<List<Corona>> getAllCorona() {
            return coronaRepository.getMutableLiveData();
        }
    }

MainActivity

    public class MainActivity extends AppCompatActivity {
        private MainViewModel mainViewModel;
        private CoronaDataAdapter coronaDataAdapter;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            ActivityMainBinding activityMainBinding =
                    DataBindingUtil.setContentView(this, R.layout.activity_main);
            // bind RecyclerView
            RecyclerView recyclerView = activityMainBinding.viewCorona;
            recyclerView.setLayoutManager(new LinearLayoutManager(this));
            recyclerView.setHasFixedSize(true);
            mainViewModel = ViewModelProviders.of(this).get(MainViewModel.class);
            coronaDataAdapter = new CoronaDataAdapter();
            recyclerView.setAdapter(coronaDataAdapter);
            getAllCorona();
        }
        private void getAllCorona() {
            mainViewModel.getAllCorona().observe(this, new Observer<List<Corona>>() {
                @Override
                public void onChanged(@Nullable List<Corona> corona) {
                    coronaDataAdapter.setCoronaList((ArrayList<Corona>) corona);
                }
            });
        }
    }

Layout

    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:bind="http://schemas.android.com/apk/res-auto"
        xmlns:card_view="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools">
        <data>
            <variable
                name="corona"
                type="com.dekikurnia.belajarmvvm.model.Corona"/>
        </data>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:adjustViewBounds="true">
            <androidx.cardview.widget.CardView
                android:id="@+id/cvCorona"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_gravity="center"
                android:layout_margin="8dp"
                android:elevation="3dp"
                card_view:cardCornerRadius="1dp">

                <androidx.constraintlayout.widget.ConstraintLayout
                    android:layout_width="match_parent"
                    android:layout_height="match_parent">

                    <TextView
                        android:id="@+id/tvProvinsi"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:layout_marginStart="8dp"
                        android:layout_marginLeft="8dp"
                        android:layout_marginTop="4dp"
                        android:layout_marginEnd="8dp"
                        android:padding="4dp"
                        android:text="@{`Provinsi : ` + corona.provinsi}"
                        android:textColor="@color/colorProvinsi"
                        android:textSize="20sp"
                        bind:layout_constraintEnd_toEndOf="parent"
                        bind:layout_constraintStart_toStartOf="parent"
                        bind:layout_constraintTop_toTopOf="parent"
                        tools:text="DKI. Jakarta" />

                    <TextView
                        android:id="@+id/tvPositif"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:layout_marginStart="8dp"
                        android:layout_marginLeft="8dp"
                        android:layout_marginTop="4dp"
                        android:layout_marginEnd="8dp"
                        android:padding="4dp"
                        android:text="@{`Positif : ` + corona.positif}"
                        android:textColor="@color/colorPositif"
                        android:textSize="14sp"
                        bind:layout_constraintEnd_toEndOf="parent"
                        bind:layout_constraintStart_toStartOf="parent"
                        bind:layout_constraintTop_toBottomOf="@+id/tvProvinsi"
                        tools:text="Positif" />

                    <TextView
                        android:id="@+id/tvSembuh"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:layout_marginStart="8dp"
                        android:layout_marginLeft="8dp"
                        android:layout_marginTop="4dp"
                        android:layout_marginEnd="8dp"
                        android:padding="4dp"
                        android:text="@{`Sembuh : ` + corona.sembuh}"
                        android:textColor="@color/colorSembuh"
                        android:textSize="14sp"
                        bind:layout_constraintEnd_toEndOf="parent"
                        bind:layout_constraintStart_toStartOf="parent"
                        bind:layout_constraintTop_toBottomOf="@+id/tvPositif"
                        tools:text="Sembuh" />

                    <TextView
                        android:id="@+id/tvMeninggal"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:layout_marginStart="8dp"
                        android:layout_marginLeft="8dp"
                        android:layout_marginTop="4dp"
                        android:layout_marginEnd="8dp"
                        android:padding="4dp"
                        android:text="@{`Meninggal : ` + corona.meninggal}"
                        android:textColor="@color/colorMeninggal"
                        android:textSize="14sp"
                        bind:layout_constraintEnd_toEndOf="parent"
                        bind:layout_constraintStart_toStartOf="parent"
                        bind:layout_constraintTop_toBottomOf="@+id/tvSembuh"
                        tools:text="Meninggal" />
                </androidx.constraintlayout.widget.ConstraintLayout>
            </androidx.cardview.widget.CardView>
        </LinearLayout>
    </layout>
dakun :

You model is wrong.Try this instead:

public class Corona {
    private Attributes attributes;

    public Attributes getAttributes() {
        return attributes;
    }
    public static class Attributes{
        @SerializedName("Provinsi")
        private String provinsi;
        @SerializedName("Kasus_Posi")
        private String positif;
        @SerializedName("Kasus_Semb")
        private String sembuh;
        @SerializedName("Kasus_Meni")
        private String meninggal;

        public String getProvinsi() {
            return provinsi;
        }

        public void setProvinsi(String provinsi) {
            this.provinsi = provinsi;
        }

        public String getPositif() {
            return positif;
        }

        public void setPositif(String positif) {
            this.positif = positif;
        }

        public String getSembuh() {
            return sembuh;
        }

        public void setSembuh(String sembuh) {
            this.sembuh = sembuh;
        }

        public String getMeninggal() {
            return meninggal;
        }

        public void setMeninggal(String meninggal) {
            this.meninggal = meninggal;
        }
    }
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=355654&siteId=1