列表片段内的排球
Volley inside listfragment
所以我有这个 ListFragment,我想在 onCreateView 中 运行 齐射请求。代码如下
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mView = inflater.inflate(R.layout.fragment_feed, container, false);
mFeedView = (ListView) mView.findViewById(android.R.id.list);
mNewPost = (FloatingActionButton) mView.findViewById(R.id.new_post);
mNewPost.setColorNormal(getResources().getColor(R.color.post_primary));
mNewPost.setColorPressed(getResources().getColor(R.color.post_pressed));
mNewPost.setColorRipple(getResources().getColor(R.color.post_rippled));
mNewPost.attachToListView(mFeedView);
mNewPost.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent newPost = new Intent(getActivity(), PostActivity.class);
newPost.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
getActivity().startActivity(newPost);
}
});
mReminderList = new ArrayList<Reminder>();
final JsonArrayRequest mRequest = new JsonArrayRequest(getFeedUrl(),
new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
for (int i = 0; i < response.length(); i++){
try {
JSONObject mItem = response.getJSONObject(i);
Reminder mReminder = new Reminder();
mReminder.setFirstname(mItem.getString(TAG_FIRSTNAME));
mReminder.setLastname(mItem.getString(TAG_LASTNAME));
mReminder.setTitle(mItem.getString(TAG_TITLE));
mReminder.setContent(mItem.getString(TAG_CONTENT));
mReminderList.add(mReminder);
} catch (JSONException e){
e.printStackTrace();
}
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
NetworkUtils.getInstance(getActivity().getApplicationContext()).addToRequestQueue(mRequest);
mFeedAdapter = new FeedAdapter(this.getActivity(), mReminderList);
setListAdapter(mFeedAdapter);
return mView;
}
适配器正常,JSON 响应正常。问题是 mReminderList 没有填充 Reminder 对象。有趣的是,只有在我使用 Volley 时才会发生这种情况。提前致谢!
您需要在解析完 json 数据后调用 adapter.notifyDataSetChanged();
。
notifyDataSetChanged()
Notifies the attached observers that the underlying data has been
changed and any View reflecting the data set should refresh itself.
@Override
public void onResponse(JSONArray response) {
for (int i = 0; i < response.length(); i++){
try {
JSONObject mItem = response.getJSONObject(i);
Reminder mReminder = new Reminder();
mReminder.setFirstname(mItem.getString(TAG_FIRSTNAME));
mReminder.setLastname(mItem.getString(TAG_LASTNAME));
mReminder.setTitle(mItem.getString(TAG_TITLE));
mReminder.setContent(mItem.getString(TAG_CONTENT));
mReminderList.add(mReminder);
} catch (JSONException e){
e.printStackTrace();
}
}
mFeedAdapter.notifyDataSetChanged();
}
您的请求是异步的,因此很可能在您已经将适配器设置为列表视图之后才收到响应。
不要将对象添加到 mReminderList
,而是在发出请求之前实例化您的 FeedAdapter
,并在获得请求时将 Reminder
对象添加到 FeedAdapter
实例响应。
并且不要忘记在添加所有 Reminders
.
后在您的适配器上调用 notifyDataSetChanged()
尝试在将项目添加到适配器后调用 adapter.notifyDataSetChanged()
,同时在调用 webservice 之前移动设置适配器的代码,因为当您尝试调用 notifyDataSetChanged()
[=21 时适配器将为空=]
此外,调用 Web 服务或长时间操作也不是一个好主意,即使它在 onCreateView()
中是异步的,因为直到控件 returns 来自它才初始化视图。
将您的 volley 相关代码从 onCreateView()
移至 onViewCreated()
或 onActivityCreated()
仅在 onCreateView
中膨胀视图并使用 onViewCreated()
中的 getView()
执行 findViewById
等并将适配器设置为 ListView
,然后调用您的网络服务。
所以我有这个 ListFragment,我想在 onCreateView 中 运行 齐射请求。代码如下
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mView = inflater.inflate(R.layout.fragment_feed, container, false);
mFeedView = (ListView) mView.findViewById(android.R.id.list);
mNewPost = (FloatingActionButton) mView.findViewById(R.id.new_post);
mNewPost.setColorNormal(getResources().getColor(R.color.post_primary));
mNewPost.setColorPressed(getResources().getColor(R.color.post_pressed));
mNewPost.setColorRipple(getResources().getColor(R.color.post_rippled));
mNewPost.attachToListView(mFeedView);
mNewPost.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent newPost = new Intent(getActivity(), PostActivity.class);
newPost.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
getActivity().startActivity(newPost);
}
});
mReminderList = new ArrayList<Reminder>();
final JsonArrayRequest mRequest = new JsonArrayRequest(getFeedUrl(),
new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
for (int i = 0; i < response.length(); i++){
try {
JSONObject mItem = response.getJSONObject(i);
Reminder mReminder = new Reminder();
mReminder.setFirstname(mItem.getString(TAG_FIRSTNAME));
mReminder.setLastname(mItem.getString(TAG_LASTNAME));
mReminder.setTitle(mItem.getString(TAG_TITLE));
mReminder.setContent(mItem.getString(TAG_CONTENT));
mReminderList.add(mReminder);
} catch (JSONException e){
e.printStackTrace();
}
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
NetworkUtils.getInstance(getActivity().getApplicationContext()).addToRequestQueue(mRequest);
mFeedAdapter = new FeedAdapter(this.getActivity(), mReminderList);
setListAdapter(mFeedAdapter);
return mView;
}
适配器正常,JSON 响应正常。问题是 mReminderList 没有填充 Reminder 对象。有趣的是,只有在我使用 Volley 时才会发生这种情况。提前致谢!
您需要在解析完 json 数据后调用 adapter.notifyDataSetChanged();
。
notifyDataSetChanged()
Notifies the attached observers that the underlying data has been changed and any View reflecting the data set should refresh itself.
@Override
public void onResponse(JSONArray response) {
for (int i = 0; i < response.length(); i++){
try {
JSONObject mItem = response.getJSONObject(i);
Reminder mReminder = new Reminder();
mReminder.setFirstname(mItem.getString(TAG_FIRSTNAME));
mReminder.setLastname(mItem.getString(TAG_LASTNAME));
mReminder.setTitle(mItem.getString(TAG_TITLE));
mReminder.setContent(mItem.getString(TAG_CONTENT));
mReminderList.add(mReminder);
} catch (JSONException e){
e.printStackTrace();
}
}
mFeedAdapter.notifyDataSetChanged();
}
您的请求是异步的,因此很可能在您已经将适配器设置为列表视图之后才收到响应。
不要将对象添加到 mReminderList
,而是在发出请求之前实例化您的 FeedAdapter
,并在获得请求时将 Reminder
对象添加到 FeedAdapter
实例响应。
并且不要忘记在添加所有 Reminders
.
notifyDataSetChanged()
尝试在将项目添加到适配器后调用 adapter.notifyDataSetChanged()
,同时在调用 webservice 之前移动设置适配器的代码,因为当您尝试调用 notifyDataSetChanged()
[=21 时适配器将为空=]
此外,调用 Web 服务或长时间操作也不是一个好主意,即使它在 onCreateView()
中是异步的,因为直到控件 returns 来自它才初始化视图。
将您的 volley 相关代码从 onCreateView()
移至 onViewCreated()
或 onActivityCreated()
仅在 onCreateView
中膨胀视图并使用 onViewCreated()
中的 getView()
执行 findViewById
等并将适配器设置为 ListView
,然后调用您的网络服务。