【问题标题】:How to populate recyclerview with compex json data using retrofit?如何使用改造使用 compex json 数据填充 recyclerview?
【发布时间】:2017-07-01 10:41:23
【问题描述】:

请指教。我有一个复杂的 json 对象,我使用 Retrofit 和 GSONConverterFactory 请求 openweathermap API。我在请求 5 天的预测时遇到问题,我无法用数据填充我的 Recyclerview,出现问题。我无法在 Retrofit 回调的 onResponse 方法中写什么。

改造请求都带有代码 200 和消息 OK。所以麻烦不在这方面。

提前谢谢你!

这是Json对象的结构

WeatherData 是我解析 Json 的根对象,请在下面找到代码。它的所有代码(以及其他 POJO 的代码都是从 jsonschema2pojo 导入的:

public class WeatherData {

@SerializedName("coord")
@Expose
private Coord coord;
@SerializedName("weather")
@Expose
private List<Weather> weather = null;
@SerializedName("base")
@Expose
private String base;
@SerializedName("main")
@Expose
private Main main;
@SerializedName("visibility")
@Expose
private Integer visibility;
@SerializedName("wind")
@Expose
private Wind wind;
@SerializedName("clouds")
@Expose
private Clouds clouds;
@SerializedName("dt")
@Expose
private Long dt;
@SerializedName("sys")
@Expose
private Sys sys;
@SerializedName("id")
@Expose
private Integer id;
@SerializedName("name")
@Expose
private String name;
@SerializedName("cod")
@Expose
private Integer cod;

public Coord getCoord() {
    return coord;
}

public void setCoord(Coord coord) {
    this.coord = coord;
}

public List<Weather> getWeather() {
    return weather;
}

public void setWeather(List<Weather> weather) {
    this.weather = weather;
}

public String getBase() {
    return base;
}

public void setBase(String base) {
    this.base = base;
}

public Main getMain() {
    return main;
}

public void setMain(Main main) {
    this.main = main;
}

public Integer getVisibility() {
    return visibility;
}

public void setVisibility(Integer visibility) {
    this.visibility = visibility;
}

public Wind getWind() {
    return wind;
}

public void setWind(Wind wind) {
    this.wind = wind;
}

public Clouds getClouds() {
    return clouds;
}

public void setClouds(Clouds clouds) {
    this.clouds = clouds;
}

public Long getDt() {
    return dt;
}

public void setDt(Long dt) {
    this.dt = dt;
}

public Sys getSys() {
    return sys;
}

public void setSys(Sys sys) {
    this.sys = sys;
}

public Integer getId() {
    return id;
}

public void setId(Integer id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public Integer getCod() {
    return cod;
}

public void setCod(Integer cod) {
    this.cod = cod;
}

这是我的 RecyclerView.Adapter

public class Forecast5DaysAdapter extends RecyclerView.Adapter<Forecast5DaysAdapter.ForecastHolder> {



List<WeatherData> mWeatherDataList;


public static class ForecastHolder extends RecyclerView.ViewHolder {

    public TextView dateOnDate;
    public ImageView weatherOnDate;
    public TextView tempOnDate;
    public TextView windSpeedOnDate;

    public ForecastHolder(View view) {
        super(view);

        dateOnDate = (TextView) view.findViewById(R.id.dateOnDate);
        windSpeedOnDate = (TextView) view.findViewById(R.id.windSpeedOnDate);
        tempOnDate = (TextView) view.findViewById(R.id.tempOnDate);
        weatherOnDate = (ImageView) view.findViewById(R.id.imageOnDate);


    }
}

public Forecast5DaysAdapter(List<WeatherData> mWeatherDataList) {

    this.mWeatherDataList = mWeatherDataList;
}

@Override
public ForecastHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    View view = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.forecast_card, parent, false);

    final ForecastHolder forecastHolder = new ForecastHolder(view);

    return forecastHolder;
}

@Override
public void onBindViewHolder(ForecastHolder holder, int position) {

    //FILLING THE CARDS IN RECYCLERVIEW WITH INFORMATION

    holder.dateOnDate.setText(mWeatherDataList.get(position).getDt().toString());
    holder.tempOnDate.setText(mWeatherDataList.get(position).getMain().getTemp().toString());
    holder.windSpeedOnDate.setText(mWeatherDataList.get(position).getWind().getSpeed().toString());
    Picasso.with(holder.weatherOnDate.getContext()).load("http://openweathermap.org/img/w/" + mWeatherDataList.get(position).getWeather().get(position).getIcon() + ".png").into(holder.weatherOnDate);

}


@Override
public int getItemCount() {
    return 0;
}

这是我要显示 Recyclerview 的类

public class Forecast5Days extends AppCompatActivity {

private static final String API_KEY = "HERE IS THE KEY";

private RecyclerView forecastRecycler;
private ArrayList<WeatherData> mWeatherData;
private Forecast5DaysAdapter forecast5DaysAdapter;


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

    forecastRecycler = (RecyclerView) findViewById(R.id.forecast_5_daysRecycler);
    RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
    forecastRecycler.setLayoutManager(layoutManager);
    final Forecast5DaysAdapter forecast5DaysAdapter = new Forecast5DaysAdapter(mWeatherData);

    forecastRecycler.setAdapter(forecast5DaysAdapter);



    Intent intent = getIntent();
    final String cityName = intent.getStringExtra("cityName");

    if (!cityName.isEmpty()) {
        Call<WeatherData> call = RetrofitBuilderHelper.weatherAPI.getForecast5Days(cityName, "ru", "metric", API_KEY);

        call.enqueue(new Callback<WeatherData>() {
            @Override
            public void onResponse(Call<WeatherData> call, Response<WeatherData> response) {

                    //????????????????

            }

            @Override
            public void onFailure(Call<WeatherData> call, Throwable t) {
                Toast toast = Toast.makeText(Forecast5Days.this, "Something went wrong with request", Toast.LENGTH_LONG);
                toast.show();
            }
        });

    } else {
        Toast toast = Toast.makeText(Forecast5Days.this, "Something went wrong with intent", Toast.LENGTH_LONG);
        toast.show();

    }


}

【问题讨论】:

    标签: android json android-recyclerview retrofit2 openweathermap


    【解决方案1】:

    你的onResponse应该是这样的

       call.enqueue(new Callback<WeatherData>() {
            @Override
            public void onResponse(Call<WeatherData> call, Response<WeatherData> response) {
    
               if(response.isSuccessful() && response.body != null) {
                    WeatherData data = response.body();
               }
    
            }
    
            @Override
            public void onFailure(Call<WeatherData> call, Throwable t) {
                Toast toast = Toast.makeText(Forecast5Days.this, "Something went wrong with request", Toast.LENGTH_LONG);
                toast.show();
            }
        });
    

    您的Call 也是Call&lt;WeatherData&gt;,它将为您提供一个对象。如果你想要一个对象列表,你的电话应该是Call&lt;List&lt;WeatherData&gt;&gt;

    我认为您希望通过Weather而不是WeatherData,所以您的onResponse 应该看起来像

          call.enqueue(new Callback<WeatherData>() {
        @Override
        public void onResponse(Call<WeatherData> call, Response<WeatherData> response) {
    
           if(response.isSuccessful() && response.body != null) {
                WeatherData data = response.body();
                List<Weather> weatherList = data.getWeatherList(); 
               //Pass this list to your adapter
           }
    
        }
    
        @Override
        public void onFailure(Call<WeatherData> call, Throwable t) {
            Toast toast = Toast.makeText(Forecast5Days.this, "Something went wrong with request", Toast.LENGTH_LONG);
            toast.show();
        }
    });
    

    【讨论】:

    • 非常感谢。那真的是我的错误,我应该看看 Listitem POJO,而不是根对象
    【解决方案2】:

    您的 JSON 返回是一个列表,而不仅仅是单个 WeatherData 对象。
    因此,您所要做的就是计算预期返回值。
    试试这个:

    Call<List<WeatherData>> call = RetrofitBuilderHelper.weatherAPI.getForecast5Days(cityName, "ru", "metric", API_KEY);
    
            call.enqueue(new Callback<List<WeatherData>>() {
    @Override
    public void onResponse(Call<List<WeatherData>> call, Response<List<WeatherData>> response) {
        forecastRecycler.weatherList = response.body();
        forecastRecycler.notifyDatasetChanged();
    }
    

    【讨论】:

    • 非常感谢您的回复,但问题是另一个问题。
    猜你喜欢
    • 2018-04-02
    • 2017-11-17
    • 1970-01-01
    • 1970-01-01
    • 2016-06-25
    • 1970-01-01
    • 2018-05-29
    • 1970-01-01
    相关资源
    最近更新 更多