我不明白以下几点。 我在调用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?
答案 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;消息。