【问题标题】:Creating list using JSON - IndexOutOfBoundsException: Invalid index 0, size is 0使用 JSON 创建列表 - IndexOutOfBoundsException:索引 0 无效,大小为 0
【发布时间】:2016-06-09 19:29:28
【问题描述】:

我正在尝试从 instagram api 获取有关特定标签的 json 数据。从响应中,我将所有 url 保存到仅具有 String url 属性的自定义类 Image 中。在每个 instagram 响应中,它有大约 20 个媒体文件,但我似乎无法构建要在我的回收站视图中显示的图像列表

response.enqueue(新回调() { @覆盖 公共无效onResponse(呼叫呼叫,响应响应){ if (response.isSuccess()) {

                mEditText.setText("secces");
                StringBuilder sb = new StringBuilder();
                try {
                    BufferedReader reader = new BufferedReader(new InputStreamReader(response.body().byteStream()));
                    String line;

                    while ((line = reader.readLine()) != null) {
                        sb.append(line);
                    }

                    JSONObject tagResponse = new JSONObject(sb.toString());

                    for (int i = 0; i < tagResponse.length(); i++) {
                        JSONObject pagination = tagResponse.getJSONObject("pagination");

                        mMaxId = pagination.getString("next_max_id");
                        mMinId= pagination.getString("next_min_id");

                        JSONObject meta = tagResponse.getJSONObject("meta");
                        JSONArray data = tagResponse.getJSONArray("data");

                        for (int j = 0; j < data.length(); j++) {

                            JSONArray tags = data.getJSONObject(j).getJSONArray("tags");


                            JSONObject images = data.getJSONObject(j).getJSONObject("images").getJSONObject("low_resolution");
                            mEditText.setText(images.getString("url"));

                            Picture picture = new Picture();
                            picture.setURL(images.getString("url"));

                            mAdapter.addImage(picture);

                        }
                    }
                    //displayResults(data);


                } catch (Exception e) {
                    e.printStackTrace();
                }

                //Log.d(TAG, "CallonResponse isSuccess " + sb.toString() + " ----- ");
            }
        }

        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {
            //Log.d(TAG, "CallonResponse onFailure! " + t.getMessage());
            t.printStackTrace();
        }
    });

当我执行以下几行时...

Picture picture = new Picture();
picture.setURL(images.getString("url"));
mAdapter.addImage(picture);

根据我的调试技能,我能够得到 images.getString("url") 我觉得图片的创建存在一些问题,但这没有意义,因为所有图片类都有一个属性,所以 addImage 中可能存在问题。下面我发布了我的适配器的代码...

公共类 ImageAdapter 扩展 RecyclerView.Adapter {

private List<Picture> mPictures;
public ImageAdapter(){
    mPictures = new ArrayList<>();
}

@Override
public Holder onCreateViewHolder(ViewGroup viewGroup, int i) {
    View row = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.sample_layout, viewGroup, false);
    return new Holder(row);
}

@Override
public void onBindViewHolder(Holder holder, int i) {
    Picture currPic = mPictures.get(i);
    Picasso.with(holder.itemView.getContext()).load(currPic.getURL()).into(holder.mPhoto1);

}

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

public void addImage(Picture picture) {
    mPictures.add(picture);
}

public class Holder extends RecyclerView.ViewHolder{

    private ImageView mPhoto1, mPhoto2;
    public Holder(View itemView) {
        super(itemView);

        mPhoto1 = (ImageView)itemView.findViewById(R.id.image1);
        //mPhoto2 = (ImageView)itemView.findViewById(R.id.image2);
    }
}

}

/已编辑:

这段代码在我最底部的主要活动中,它设置了视图......它适用于不同的项目,所以我认为这也是我将如何设置它的方式

private void configViews() {
        mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        //mLayoutManager = new StaggeredGridLayoutManager(VR_SPAN_COUNT, StaggeredGridLayoutManager.VERTICAL);
        mRecyclerView.setHasFixedSize(true);
        mRecyclerView.setRecycledViewPool(new RecyclerView.RecycledViewPool());
        mRecyclerView.setLayoutManager(mLayoutManager);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.VERTICAL, false));
//        mAdapter = new ImageAdapter();
//        mRecyclerView.setAdapter(mAdapter);
    }    

【问题讨论】:

  • @Override public int getItemCount() { return 600; } 为什么总是返回 600?
  • 你说得对,那只是我在胡闹...我已根据其他建议更改了这一点,感谢您指出!

标签: android list instagram


【解决方案1】:

问题是您使用空数组 mPictures 创建适配器。

您必须执行以下操作:

在您的活动/片段中,您必须创建图片列表,例如:

List&lt;Picture&gt; mPictures = new ArrayList&lt;Picture&gt;;

当你迭代你的响应(数据)时,你必须使用 mPictures.add(picture); 而不是 mAdapter.addImage(picture);

在循环之后,您必须创建适配器ImageAdapter mAdapter = new ImageAdapter(mPictures); 并将其设置为 Recycler 视图 - mRecyclerView.setAdapter(mAdapter);

您还必须像这样更改适配器构造:

public ImageAdapter(List<Picture> pictures){
        mPictures = pictures;
}

适配器中的 getItemCount() 方法必须如下所示:

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

适配器中的 addImage() 方法不再需要。就是这样。

【讨论】:

  • 哇,你的方法更有意义,我现在意识到我根本没有创建数组,哈哈。所以我现在就尝试了,我仍然遇到同样的错误,但我仍然觉得我朝着正确的方向迈出了一步。目前,一旦完成数据处理,我就会将 mPictures 放入我的适配器中。
  • 另外,我真的对 recyclerview 感到困惑,我认为这可能存在问题。我会尝试编辑并向您展示我是如何设置它的。
  • 当我调试它时,我看到数组正在被填充。它的大小正在增加,并且它的图像越来越多。当我访问单个元素并记录它们时,我可以看到网址。
  • 另外,我刚刚意识到,即使我在文件顶部定义了我的数组......它似乎在响应方法之外变成了大小 0
  • 我终于让它工作了。老实说,我不知道它为什么会起作用,但是我将一些东西从 configviews 移到了 oncreate 的顶部。比如实例化我的布局管理器并将其设置为适配器。我知道事后看来这是有道理的,但有人可以解释一下吗?另外我的 viewconfig 方法中的其他东西呢,我的意思是我现在不使用它们,但它们是做什么的??
【解决方案2】:

由于您有硬编码的 600 个项目,recyclerview 想要显示项目并要求第一个元素 (0)

Picture currPic = mPictures.get(i);

然后抛出异常,因为你没有图片。

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

mAdapter.addImage(picture);
recyclerView.notifyItemInserted(adapter.getItemCount()-1)

应该做正确的事

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-15
    • 2019-07-19
    • 1970-01-01
    • 2018-06-11
    • 1970-01-01
    相关资源
    最近更新 更多