将<model>传递给嵌套的Adapater时列出null

时间:2017-03-02 01:34:47

标签: android android-recyclerview android-adapter

在我从网络调用设置所有数据后添加模型时,不确定为什么列表为空。

如果我使用finalHourList,如果我打印到logcat,数据会显示在日志中。我不能使用finalHourList,因为我已将它绑定到适配器内的HourlyForcast模型。所以,我不能将适配器传递给一个字符串,并且必须将它传递给List。在将数据设置为预测后,不确定为什么finalHourList.add(forecast);为空。

硬编码列表没有任何问题,但现在我尝试使用从网络调用返回的数据填充RecyclerView。

public class HomeRecyclerAdapter extends RecyclerView.Adapter<HomeRecyclerAdapter.ViewHolder> {
    private ArrayList<String> dates;
    private Context context;
    private String defaultZipcode = "55372";
    private String mEnglishTemp, mCivilTime, mCondtion, mConditionIcon;
    private List<HourlyForcast> finalHourlyList = new ArrayList<>();
    HourlyForcastAdapter adapter;
    private HourlyForcast forecast;

    public HomeRecyclerAdapter(ArrayList<String> dates) {
        this.dates = dates;
    }

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

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        Typeface titleStyle = Typeface.createFromAsset(context.getAssets(),
                "font/Roboto-Medium.ttf");
        holder.mDate.setTypeface(titleStyle);
        holder.mDate.setText(dates.get(position));

        getHourlyWeather(defaultZipcode);

        GridLayoutManager gridLayoutManager = new GridLayoutManager(context, 4);
        holder.mInnerRecycler.setHasFixedSize(true);
        holder.mInnerRecycler.setLayoutManager(gridLayoutManager);
        adapter = new HourlyForcastAdapter(context, finalHourlyList);
        holder.mInnerRecycler.setAdapter(adapter);
    }

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

    public static class ViewHolder extends RecyclerView.ViewHolder {
        private TextView mDate;
        private RecyclerView mInnerRecycler;

        ViewHolder(View view) {
            super(view);
            mDate = (TextView) view.findViewById(R.id.tvDate);
            mInnerRecycler = (RecyclerView) view.findViewById(R.id.hourlyRecycler);
        }
    }

    private List<HourlyForcast> getAllItemList() {

        List<HourlyForcast> allHours = new ArrayList<>();
        allHours.add(new HourlyForcast("4:00 PM", "8°", "Overcast"));
        allHours.add(new HourlyForcast("5:00 PM", "6°", "Sunny"));
        allHours.add(new HourlyForcast("6:00 PM", "5°", "Sunny"));
        allHours.add(new HourlyForcast("7:00 PM", "3°", "Rainy"));
        allHours.add(new HourlyForcast("8:00 PM", "3°", "Sunny"));
        allHours.add(new HourlyForcast("9:00 PM", "3°", "Snowing"));
        allHours.add(new HourlyForcast("10:00 PM", "4°", "Sunny"));
        allHours.add(new HourlyForcast("11:00 PM", "60°", "Sunny"));
        return allHours;
    }

    public void getHourlyWeather(String zipCode) {
        OkHttpClient client = new OkHttpClient();

        HttpUrl.Builder urlBuilder = HttpUrl.parse(context.getString
                (R.string.hourlyForcastURL)).newBuilder();
        urlBuilder.addPathSegment(zipCode + ".json");
        String url = urlBuilder.build().toString();

        Request request = new Request.Builder()
                .url(url)
                .build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                e.printStackTrace();
                call.cancel();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String mResponse = response.body().string();
                try {
                    JSONObject hourlyObject = new JSONObject(mResponse);
                    JSONArray hourForcastArray = hourlyObject.getJSONArray("hourly_forecast");
                    for (int i = 0; i < hourForcastArray.length(); i++) {
                        JSONObject HourlyObject = hourForcastArray.getJSONObject(i);
                        JSONObject mTemp = HourlyObject.getJSONObject("temp");
                        mConditionIcon = HourlyObject.getString("icon_url");
                        mEnglishTemp = mTemp.getString("english");
                        mCondtion = HourlyObject.getString("condition");
                        JSONObject FCTRemoveal = HourlyObject.getJSONObject("FCTTIME");
                        mCivilTime = FCTRemoveal.getString("civil");

                        forecast = new HourlyForcast();
                        forecast.setTime(mCivilTime);
                        forecast.setCondition(mCondtion);
                        forecast.setDegrees(mEnglishTemp);

                        /*finalHourlyList = new ArrayList<>();
                        finalHourlyList.add(mEnglishTemp);
                        finalHourlyList.add(mCivilTime);
                        finalHourlyList.add(mCondtion);*/

                        finalHourlyList = new ArrayList<>();
                        finalHourlyList.add(forecast);
                        Log.i("HOURLYLIST", finalHourlyList.toString());
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

适配器我将列表传递给

public class HourlyForcastAdapter extends RecyclerView.Adapter<HourlyForcastAdapter.HourlyViewHolder> {
    private List<HourlyForcast> itemList;
    private Context context;

    public HourlyForcastAdapter(Context context, List<HourlyForcast> itemList) {
        this.itemList = itemList;
        this.context = context;
    }

    @Override
    public HourlyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.hourly_single, parent, false);
        return new HourlyViewHolder(view);
    }

    @Override
    public void onBindViewHolder(HourlyViewHolder holder, int position) {
        Typeface regStyle = Typeface.createFromAsset(context.getAssets(),
                "font/Roboto-Regular.ttf");
        holder.mTimeText.setTypeface(regStyle);
        holder.mDegreeText.setTypeface(regStyle);
        holder.mTimeText.setText(itemList.get(position).getTime());
        holder.mDegreeText.setText(itemList.get(position).getDegrees());
        holder.mWeatherIcon.setText(itemList.get(position).getCondition());
     //   holder.mWeatherIcon.setImageResource(itemList.get(position).getImageID());
    }

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

    public static class HourlyViewHolder extends RecyclerView.ViewHolder {
        TextView mTimeText, mDegreeText, mWeatherIcon;
      //  ImageView mWeatherIcon;

        public HourlyViewHolder(View itemView) {
            super(itemView);
            mTimeText = (TextView) itemView.findViewById(R.id.timePlaceHolder);
            mDegreeText = (TextView) itemView.findViewById(R.id.degreePlaceHolder);
            mWeatherIcon = (TextView) itemView.findViewById(R.id.weatherIconHolder);
        }
    }
}

2 个答案:

答案 0 :(得分:1)

不要在适配器内部进行网络调用,而是将其放在您调用HomeRecyclerAdapter的类中,并将其命名为MainActivity。并在HomeRecyclerAdapter的构造函数中传递List。

在MainActivity中

  • final RecyclerView.Adapter adapter = new HomeRecyclerAdapter(days,finalHourlyList);

  • getHourlyWeather(String zipCode)

在HomeRecyclerAdapter中

public HomeRecyclerAdapter(ArrayList<String> dates,ArrayList<HourlyForcast> finalHourlyList) {
    this.dates = dates;
    this.finalHourlyList = finalHourlyList;
}

答案 1 :(得分:0)

好吧,我想出来了,这就是发生的事情。

HourlyForcastAdapter adapter = new HourlyForcastAdapter(context, finalHourlyList); //passing this list to adapter

该行传递一个空引用,当前没有数据。因此,你最初是空的,所以你得到一些空的东西。要解决此问题,请在接受finalHourlyList的下一个适配器类中添加一个方法。然后,当网络呼叫完成后,手动调用此方法,从而传递新更新的列表。

同样在下一个适配器中,调用notifyDataSetChange以发出刷新信号。

 adapter.notifyDataSetChanged();

有意义吗? 主要原因是因为回收器在连接适配器时急切地显示数据。但是没有数据,所以它吓坏了。

private List<HourlyForcast> finalHourlyList;更改为

private List<HourlyForcast> finalHourlyList = new ArrayList<>();

在最顶端。

---------------------------------------------------------------------
 forecast = new HourlyForcast();
                    forecast.setTime(mCivilTime);
                    forecast.setCondition(mCondtion);
                    forecast.setDegrees(mEnglishTemp);

                    /*finalHourlyList = new ArrayList<>();
                    finalHourlyList.add(mEnglishTemp);
                    finalHourlyList.add(mCivilTime);
                    finalHourlyList.add(mCondtion);*/

                    finalHourlyList = new ArrayList<>();
                    finalHourlyList.add(forecast);

下面的这一行将起作用,因为它目前填充了数据。但我所说的是,当你在onBind adapter = new HourlyForcastAdapter(context, finalHourlyList);中调用此行时,还没有数据。你在想什么是这个,因为我在做出任何改变之前设置数据会自动反映,但不会。您必须触发更新并让回收者视图知道有新内容可用。因此您需要更新内部回收器视图适配器。模仿这种逻辑。

       holder.mInnerRecycler. adapter.notifyDataSetChanged();