Firstly sorry for my bad english. My issue is, I am trying to make a Weather app using Weather API. I want to show 5 day forecast using recyclerview adapter. I add the data to arraylist, that I get from API and it should go to my adapter class. It needs to show the data added to the arraylist there but it doesn't and arraylist size is always zero.
My recyclerview class is forecast
oncreate
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_forecast);
Intent intent = getIntent();
Latitude = intent.getDoubleExtra("lat",0);
Longitude = intent.getDoubleExtra("long",0);
System.out.println("LATİTUDE " Latitude " Longitude " Longitude);//i just experimented to
check if latitude and
longitude come
init();
}
init()
public void init(){
arrayList = new ArrayList<>();
forecast_back_icon = findViewById(R.id.forecast_back_icon);
recyclerviewforecast = findViewById(R.id.RecyclerviewForecast);
get_forecast_data(Latitude,Longitude);
forecastAdapter = new ForecastAdapter(arrayList);
recyclerviewforecast.setAdapter(forecastAdapter);
recyclerviewforecast.setLayoutManager(new LinearLayoutManager(forecast.this));
forecast_back_icon();
}
get_forecast_data() funct
public void get_forecast_data(Double Lat, Double Long){
//EXAMPLE URL
//https://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&appid={API key}
API_KEY_FORECAST = "c29ecfafd4a70caad8fee38d6054bfc7";
URL_FORECAST = "https://api.openweathermap.org/data/2.5/onecall?lat=" Lat "&lon=" Long "&exclude=current,minutely,hourly,alerts&appid=" API_KEY_FORECAST;
RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, URL_FORECAST, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
JSONArray daily = response.getJSONArray("daily");
for(int i=0;i<daily.length();i ){
String temp = daily.getJSONObject(i).getJSONObject("temp").getString("day");
String feels_like = daily.getJSONObject(i).getJSONObject("feels_like").getString("day");
String pressure = daily.getJSONObject(i).getString("pressure");
String humidity = daily.getJSONObject(i).getString("humidity");
String wind_speed = daily.getJSONObject(i).getString("wind_speed");
String icon = daily.getJSONObject(i).getJSONArray("weather").getJSONObject(0).getString("icon");
String description = daily.getJSONObject(i).getJSONArray("weather").getJSONObject(0).getString("description");
arrayList.add(new RecyclerviewModel(temp,humidity,feels_like,pressure,description,wind_speed,icon));
}
}
catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
queue.add(request);
System.out.println("forecast class arraylist size : --> " arrayList.size());
}
When I check at the bottom, the size of the arraylist is zero
my forecast adapter class
public class ForecastAdapter extends RecyclerView.Adapter<ForecastAdapter.MyForecastViewHolder> {
ArrayList<RecyclerviewModel> ForecastArraylist;
public ForecastAdapter(ArrayList<RecyclerviewModel> ForecastArraylist){
this.ForecastArraylist = ForecastArraylist;
System.out.println("ForecastAdapter arraylist size : --- > " ForecastArraylist.size());
}
@NonNull
@Override
public MyForecastViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
RecyclerviewForecastRowBinding recyclerviewForecastRowBinding = RecyclerviewForecastRowBinding.inflate(LayoutInflater.from(parent.getContext()),parent,false);
return new MyForecastViewHolder(recyclerviewForecastRowBinding);
}
@Override
public void onBindViewHolder(@NonNull MyForecastViewHolder holder, int position) {
System.out.println("we are in onbindviewholder.... ");
Double temperature = Double.parseDouble(ForecastArraylist.get(position).getTemperature()) - 273.15;
System.out.println(temperature);
Double feels_like = Double.parseDouble(ForecastArraylist.get(position).getFeels_like()) - 273.15;
holder.binding.txtRecyclerviewTemp.setText(temperature.toString().substring(0,4) "°");
holder.binding.txtRecyclerviewFeelslike.setText(feels_like.toString().substring(0,4) "°");
holder.binding.txtRecyclerviewHumidity.setText("%" ForecastArraylist.get(position).getHumadity());
holder.binding.txtRecyclerviewPressure.setText(ForecastArraylist.get(position).getPressure() "hPa");
holder.binding.txtRecyclerviewWindSpeed.setText(ForecastArraylist.get(position).getWind_speed() "km/h");
holder.binding.txtRecyclerviewCloud.setText(ForecastArraylist.get(position).getDescription());
String icon_id = ForecastArraylist.get(position).getId();
load_weather_icon(icon_id,holder);
}
@Override
public int getItemCount() {
return ForecastArraylist.size();
}
public class MyForecastViewHolder extends RecyclerView.ViewHolder{
private RecyclerviewForecastRowBinding binding;
public MyForecastViewHolder(@NonNull RecyclerviewForecastRowBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
}
public void load_weather_icon(String id,MyForecastViewHolder holder ){
int id1 = Integer.valueOf(id);
if(id1>=200 && id1 <= 232){
holder.binding.recyclerviewCloudImg.setBackgroundResource(R.drawable.thunderstorm);
}
else if(id1>=300 && id1<= 321){
holder.binding.recyclerviewCloudImg.setBackgroundResource(R.drawable.showerrain);
}
else if(id1>=500 && id1<= 504){
holder.binding.recyclerviewCloudImg.setBackgroundResource(R.drawable.rain);
}
else if(id1 == 511){
holder.binding.recyclerviewCloudImg.setBackgroundResource(R.drawable.snow);
}
else if(id1>=520 && id1<= 531){
holder.binding.recyclerviewCloudImg.setBackgroundResource(R.drawable.showerrain);
}
else if(id1>=600 && id1<= 622){
holder.binding.recyclerviewCloudImg.setBackgroundResource(R.drawable.snow);
}
else if(id1>=701 && id1<= 781){
holder.binding.recyclerviewCloudImg.setBackgroundResource(R.drawable.mist);
}
else if(id1 == 800 ){
holder.binding.recyclerviewCloudImg.setBackgroundResource(R.drawable.clearsky);
}
else if(id1 == 801){
holder.binding.recyclerviewCloudImg.setBackgroundResource(R.drawable.fewclouds);
}
else if(id1 == 802){
holder.binding.recyclerviewCloudImg.setBackgroundResource(R.drawable.scatteredclouds);
}
else if(id1 == 803){
holder.binding.recyclerviewCloudImg.setBackgroundResource(R.drawable.brokenclouds);
}
else if(id1 == 804){
holder.binding.recyclerviewCloudImg.setBackgroundResource(R.drawable.brokenclouds);
}
}
}
I can't see 'we are in onbindviewholder' in my forecast adapter
forecast xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".forecast"
android:orientation="vertical"
android:id="@ id/forecastLayout">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:id="@ id/Toolbarcities">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@ id/toolbarconstraintforecast"
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.Toolbar
android:id="@ id/MyToolbarforecast"
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:titleTextColor="@color/white"
>
<ImageView
android:id="@ id/forecast_back_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/cities_back_icon"
></ImageView>
</androidx.appcompat.widget.Toolbar>
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@ id/RecyclerviewForecast"
android:layout_width="match_parent"
android:layout_height="match_parent" />
CodePudding user response:
The problem here is, that you have created the adapter with an empty array list and assigned it to the Recyclerview before the Volley request is processed and the array list is filled. There are 2 ways you can fix this. First is to create the adapter and set the adapter inside the OnResponse method of the Volley request. Or else you can create a method in the adapter that updates the array list and notify the adapter that the dataset is changed. I hoped you'd understand this.
First is the easiest