将Adapter设置为RecyclerView后解析JSON。仍显示的项目

时间:2017-11-29 19:45:46

标签: android json android-recyclerview android-volley

我不明白以下几点。 我在调用parseJSON()之前创建了Adapter,并为它设置了一个新的空ArrayList。我没有调用notifyDataSetChanged,仍显示Items。为什么不空?

public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private ExampleAdapter mAdapter;
private ArrayList<ExampleItem> mExampleList;
private RequestQueue mRequestQueue;

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

    mRecyclerView = findViewById(R.id.recycler_view);
    mRecyclerView.setHasFixedSize(true);
    mRecyclerView.setLayoutManager(new LinearLayoutManager(this));

    mExampleList = new ArrayList<>();
    mAdapter = new ExampleAdapter(MainActivity.this, mExampleList);
    mRecyclerView.setAdapter(mAdapter);

    mRequestQueue = Volley.newRequestQueue(this);

    parseJSON();
}

private void parseJSON() {
    String url = "https://pixabay.com/api/?key=5303976-fd6581ad4ac165d1b75cc15b3&q=kitten&image_type=photo&pretty=true";

    JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null,
            new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {
                    try {
                        JSONArray jsonArray = response.getJSONArray("hits");

                        for (int i = 0; i < jsonArray.length(); i++) {
                            JSONObject hit = jsonArray.getJSONObject(i);

                            String userName = hit.getString("user");
                            String imageUrl = hit.getString("webformatURL");
                            int likeCount = hit.getInt("likes");

                            mExampleList.add(new ExampleItem(imageUrl, userName, likeCount));
                        }

                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            error.printStackTrace();
        }
    });

    mRequestQueue.add(request);
}
}

此处适当放置适配器的位置在哪里?我应该在解析数据后直接在parseJSON方法中设置它吗?或者我应该像现在一样设置它,然后调用notifyDataSetChanged?

1 个答案:

答案 0 :(得分:1)

  

我在调用parseJSON()之前创建了Adapter,并为它设置了一个新的空ArrayList。我没有调用notifyDataSetChanged,仍显示Items。为什么不空?

我没有您的适配器代码,所以我无法肯定地说,但我敢打赌您的适配器和您的活动正在共享对mExampleList的引用。想象一下你的适配器看起来像这样:

public class ExampleAdapter ... {

    private ArrayList<ExampleItem> list;

    public ExampleAdapter(Context context, ArrayList<ExampleItem> list) {
        ...
        this.list = list;
        ...
    }
}

当您致电new ExampleAdapter(MainActivity.this, mExampleList)然后将项目添加到mExampleList时,您还将向适配器添加项目。如果您希望适配器与任何传递它的人共享列表,您应该在适配器的构造函数中复制一份:

this.list = new ArrayList<>(list);
  

此处适当放置适配器的位置在哪里?我应该在解析数据后直接在parseJSON方法中设置它吗?或者我应该像现在一样设置它,然后调用notifyDataSetChanged?

您现在将适配器分配给recyclerview的方式很好。只要您通知适配器更改,就可以在分配了adpater后更新支持列表。

更新

  

请注意,解析后我不会调用notifyDataSetChanged,这就是为什么我这么困惑

如果JsonObjectRequest完成得足够快,那就无所谓了。只要列表在RecyclerView首次绘制时有数据,就会显示该数据。

作为证据,我写了这个小应用程序,它创建一个空字符串列表,将其传递给适配器,然后更新它:

strings = new ArrayList<>();

RecyclerView recycler = findViewById(R.id.recycler);
recycler.setAdapter(new MyAdapter(strings));

new Handler().postDelayed(new Runnable() {
    @Override
    public void run() {
        strings.add("Hello");
        strings.add("world!");
    }
}, 30);

30毫秒的延迟足以跳过至少一帧绘图,但RecyclerView仍然显示我的&#34; hello world&#34;消息。