放在哪里 adapter.notifyDataSetChanged();使用 Volley 时
Where to place adapter.notifyDataSetChanged(); when using Volley
此代码运行良好,将我的 JSON 响应显示到数组列表中。问题是,每次我点击按钮再次显示列表时,它只是简单地重复了之前的 JSON 响应,导致重复结果列表。
如何让它在我每次单击按钮时刷新数组列表,从而删除所有以前的结果?我需要放置另一个 notifyDataSetChanged 吗?如果有,在哪里?
Details.java代码:
public class Details extends AppCompatActivity {
private static final String TAG = Details.class.getSimpleName();
String url="removed";
private Button ShowDetailsButton;
private Button AddDetails;
private CustomListAdapter adapter;
private ProgressDialog pDialog;
private List<LoadUsers> mList = new ArrayList<LoadUsers>();
private ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.studio_student_view);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
listView = (ListView) findViewById(R.id.lv);
adapter = new CustomListAdapter(this, mList);
listView.setAdapter(adapter);
ShowDetailsButton = (Button) findViewById(R.id.show_details);
AddDetails = (Button) findViewById(R.id.add_details);
// Progress dialog
pDialog = new ProgressDialog(this);
pDialog.setCancelable(false);
ShowDetailsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// Creating volley request obj
JsonArrayRequest studentReq = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
hidePDialog();
// Parsing json
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
LoadUsers details = new LoadUsers();
details.setTitle(obj.getString("name"));
details.setThumbnailUrl(obj.getString("image"));
details.setEmail(obj.getString("email"));
details.setPhone(obj.getString("phone"));
// adding
mList.add(details);
} catch (JSONException e) {
e.printStackTrace();
}
}
// notifying list adapter about data changes
// so that it renders the list view with updated data
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
hidePDialog();
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(studentReq);
}
});
}
public void hidePDialog() {
if (pDialog != null) {
pDialog.dismiss();
pDialog = null;
}
}
public void onDestroy() {
super.onDestroy();
hidePDialog();
}
}
CustomListAdapter.java代码:
public class CustomListAdapter extends BaseAdapter {
private Activity activity;
private LayoutInflater inflater;
private List<LoadUsers> usersItems;
ImageLoader imageLoader = AppController.getInstance().getImageLoader();
public CustomListAdapter(Activity activity, List<LoadUsers> usersItems) {
this.activity = activity;
this.usersItems = usersItems;
}
@Override
public int getCount() {
return usersItems.size();
}
@Override
public Object getItem(int location) {
return usersItems.get(location);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (inflater == null)
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null)
convertView = inflater.inflate(R.layout.list_row, null);
if (imageLoader == null)
imageLoader = AppController.getInstance().getImageLoader();
NetworkImageView thumbNail = (NetworkImageView) convertView.findViewById(R.id.thumbnail);
TextView title = (TextView) convertView.findViewById(R.id.title);
TextView email = (TextView) convertView.findViewById(R.id.lvemail);
TextView phone = (TextView) convertView.findViewById(R.id.lvphone);
// getting user data for the row
LoadUsers m = usersItems.get(position);
// thumbnail image
thumbNail.setImageUrl(m.getThumbnailUrl(), imageLoader);
// title
title.setText(m.getTitle());
// email
email.setText("Email: " + String.valueOf(m.getEmail()));
// phone
phone.setText("Phone: " + String.valueOf(m.getPhone()));
return convertView;
}
}
错误:
数据重复,因为您没有清除具有以前数据集的 ArrayList。
解法:
在进行 API 调用之前清除 ArrayList。在您的情况下,这应该是按钮点击侦听器代码的第一行!
// clear collection
mList.clear();
您可以在 public void onResponse(JSONArray response)
之后添加 mList.clear()
您也可以使用 mList.addAll()
方法添加适配器中的所有元素并通知一次,否则如果您使用 mList.add()
,则每次添加单个项目时都会通知。
请注意,通知是在内部完成的。
谢谢。成功了!
解决方案:
public class Details extends AppCompatActivity {
private static final String TAG = Details.class.getSimpleName();
String url="removed";
private Button ShowDetailsButton;
private Button AddDetails;
private CustomListAdapter adapter;
private ProgressDialog pDialog;
private List<LoadUsers> mList = new ArrayList<LoadUsers>();
private ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.studio_student_view);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
listView = (ListView) findViewById(R.id.lv);
adapter = new CustomListAdapter(this, mList);
listView.setAdapter(adapter);
ShowDetailsButton = (Button) findViewById(R.id.show_details);
AddDetails = (Button) findViewById(R.id.add_details);
// Progress dialog
pDialog = new ProgressDialog(this);
pDialog.setCancelable(false);
ShowDetailsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mList.clear();
// Creating volley request obj
JsonArrayRequest studentReq = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
hidePDialog();
// Parsing json
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
LoadUsers details = new LoadUsers();
details.setTitle(obj.getString("name"));
details.setThumbnailUrl(obj.getString("image"));
details.setEmail(obj.getString("email"));
details.setPhone(obj.getString("phone"));
// adding
mList.add(details);
} catch (JSONException e) {
e.printStackTrace();
}
}
// notifying list adapter about data changes
// so that it renders the list view with updated data
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
hidePDialog();
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(studentReq);
}
});
}
public void hidePDialog() {
if (pDialog != null) {
pDialog.dismiss();
pDialog = null;
}
}
public void onDestroy() {
super.onDestroy();
hidePDialog();
}
}
我们这里有两种方法,
- 您想清除所有数据并完全更新列表。
- 您想添加一些新数据以列出并显示旧数据 + 新数据
方法一:
@Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
hidePDialog();
// CLEAR YOUR OLD DATA HERE
mList.clear();
// Parsing json
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
LoadUsers details = new LoadUsers();
details.setTitle(obj.getString("name"));
details.setThumbnailUrl(obj.getString("image"));
details.setEmail(obj.getString("email"));
details.setPhone(obj.getString("phone"));
// adding
mList.add(details);
} catch (JSONException e) {
e.printStackTrace();
}
}
// notifying list adapter about data changes
// so that it renders the list view with updated data
adapter.notifyDataSetChanged();
按照这种方法,您的列表将再次更新。
方法二:
您只想添加新数据,并且想为新添加的项目显示动画。
@Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
hidePDialog();
// MAKE A NEW LIST HERE AND ADD NEW DATA TO IT
private List<LoadUsers> mListNewItems = new ArrayList<LoadUsers>();
// Parsing json
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
LoadUsers details = new LoadUsers();
details.setTitle(obj.getString("name"));
details.setThumbnailUrl(obj.getString("image"));
details.setEmail(obj.getString("email"));
details.setPhone(obj.getString("phone"));
// ADD NEW DATA TO NEW LIST
mListNewItems.add(details);
} catch (JSONException e) {
e.printStackTrace();
}
// IMPORTANT TASK SHOULD DONE HERE
// Get Old Size Of the List before adding new data to notify new inserted items
int oldSize=mList.getSize();
// here we check whether we have such a data in our list. if we had, we dnt add that, otherwise add new data to our list
for (int i=0;i<mListNewItems.size();i++){
if(!mList.contain(mListNewItems.get(i))){
mList.add(mListNewItems.get(i));
}
}
//check how many new items added
int numberOfNewItems=mList.getSize()-oldSize;
// Here you should use notifyItemRangeInserted instead of notifyDataSetChange as it is less time consuming than notifyDataSetChange and also it let you to show animation for new added items.
adapter.notifyItemRangeInserted(oldSize,numberOfNewItems);
}
此代码运行良好,将我的 JSON 响应显示到数组列表中。问题是,每次我点击按钮再次显示列表时,它只是简单地重复了之前的 JSON 响应,导致重复结果列表。
如何让它在我每次单击按钮时刷新数组列表,从而删除所有以前的结果?我需要放置另一个 notifyDataSetChanged 吗?如果有,在哪里?
Details.java代码:
public class Details extends AppCompatActivity {
private static final String TAG = Details.class.getSimpleName();
String url="removed";
private Button ShowDetailsButton;
private Button AddDetails;
private CustomListAdapter adapter;
private ProgressDialog pDialog;
private List<LoadUsers> mList = new ArrayList<LoadUsers>();
private ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.studio_student_view);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
listView = (ListView) findViewById(R.id.lv);
adapter = new CustomListAdapter(this, mList);
listView.setAdapter(adapter);
ShowDetailsButton = (Button) findViewById(R.id.show_details);
AddDetails = (Button) findViewById(R.id.add_details);
// Progress dialog
pDialog = new ProgressDialog(this);
pDialog.setCancelable(false);
ShowDetailsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// Creating volley request obj
JsonArrayRequest studentReq = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
hidePDialog();
// Parsing json
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
LoadUsers details = new LoadUsers();
details.setTitle(obj.getString("name"));
details.setThumbnailUrl(obj.getString("image"));
details.setEmail(obj.getString("email"));
details.setPhone(obj.getString("phone"));
// adding
mList.add(details);
} catch (JSONException e) {
e.printStackTrace();
}
}
// notifying list adapter about data changes
// so that it renders the list view with updated data
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
hidePDialog();
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(studentReq);
}
});
}
public void hidePDialog() {
if (pDialog != null) {
pDialog.dismiss();
pDialog = null;
}
}
public void onDestroy() {
super.onDestroy();
hidePDialog();
}
}
CustomListAdapter.java代码:
public class CustomListAdapter extends BaseAdapter {
private Activity activity;
private LayoutInflater inflater;
private List<LoadUsers> usersItems;
ImageLoader imageLoader = AppController.getInstance().getImageLoader();
public CustomListAdapter(Activity activity, List<LoadUsers> usersItems) {
this.activity = activity;
this.usersItems = usersItems;
}
@Override
public int getCount() {
return usersItems.size();
}
@Override
public Object getItem(int location) {
return usersItems.get(location);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (inflater == null)
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null)
convertView = inflater.inflate(R.layout.list_row, null);
if (imageLoader == null)
imageLoader = AppController.getInstance().getImageLoader();
NetworkImageView thumbNail = (NetworkImageView) convertView.findViewById(R.id.thumbnail);
TextView title = (TextView) convertView.findViewById(R.id.title);
TextView email = (TextView) convertView.findViewById(R.id.lvemail);
TextView phone = (TextView) convertView.findViewById(R.id.lvphone);
// getting user data for the row
LoadUsers m = usersItems.get(position);
// thumbnail image
thumbNail.setImageUrl(m.getThumbnailUrl(), imageLoader);
// title
title.setText(m.getTitle());
// email
email.setText("Email: " + String.valueOf(m.getEmail()));
// phone
phone.setText("Phone: " + String.valueOf(m.getPhone()));
return convertView;
}
}
错误:
数据重复,因为您没有清除具有以前数据集的 ArrayList。
解法: 在进行 API 调用之前清除 ArrayList。在您的情况下,这应该是按钮点击侦听器代码的第一行!
// clear collection
mList.clear();
您可以在 public void onResponse(JSONArray response)
之后添加 mList.clear()
您也可以使用 mList.addAll()
方法添加适配器中的所有元素并通知一次,否则如果您使用 mList.add()
,则每次添加单个项目时都会通知。
请注意,通知是在内部完成的。
谢谢。成功了!
解决方案:
public class Details extends AppCompatActivity {
private static final String TAG = Details.class.getSimpleName();
String url="removed";
private Button ShowDetailsButton;
private Button AddDetails;
private CustomListAdapter adapter;
private ProgressDialog pDialog;
private List<LoadUsers> mList = new ArrayList<LoadUsers>();
private ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.studio_student_view);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
listView = (ListView) findViewById(R.id.lv);
adapter = new CustomListAdapter(this, mList);
listView.setAdapter(adapter);
ShowDetailsButton = (Button) findViewById(R.id.show_details);
AddDetails = (Button) findViewById(R.id.add_details);
// Progress dialog
pDialog = new ProgressDialog(this);
pDialog.setCancelable(false);
ShowDetailsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mList.clear();
// Creating volley request obj
JsonArrayRequest studentReq = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
hidePDialog();
// Parsing json
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
LoadUsers details = new LoadUsers();
details.setTitle(obj.getString("name"));
details.setThumbnailUrl(obj.getString("image"));
details.setEmail(obj.getString("email"));
details.setPhone(obj.getString("phone"));
// adding
mList.add(details);
} catch (JSONException e) {
e.printStackTrace();
}
}
// notifying list adapter about data changes
// so that it renders the list view with updated data
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
hidePDialog();
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(studentReq);
}
});
}
public void hidePDialog() {
if (pDialog != null) {
pDialog.dismiss();
pDialog = null;
}
}
public void onDestroy() {
super.onDestroy();
hidePDialog();
}
}
我们这里有两种方法,
- 您想清除所有数据并完全更新列表。
- 您想添加一些新数据以列出并显示旧数据 + 新数据
方法一:
@Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
hidePDialog();
// CLEAR YOUR OLD DATA HERE
mList.clear();
// Parsing json
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
LoadUsers details = new LoadUsers();
details.setTitle(obj.getString("name"));
details.setThumbnailUrl(obj.getString("image"));
details.setEmail(obj.getString("email"));
details.setPhone(obj.getString("phone"));
// adding
mList.add(details);
} catch (JSONException e) {
e.printStackTrace();
}
}
// notifying list adapter about data changes
// so that it renders the list view with updated data
adapter.notifyDataSetChanged();
按照这种方法,您的列表将再次更新。
方法二:
您只想添加新数据,并且想为新添加的项目显示动画。
@Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
hidePDialog();
// MAKE A NEW LIST HERE AND ADD NEW DATA TO IT
private List<LoadUsers> mListNewItems = new ArrayList<LoadUsers>();
// Parsing json
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
LoadUsers details = new LoadUsers();
details.setTitle(obj.getString("name"));
details.setThumbnailUrl(obj.getString("image"));
details.setEmail(obj.getString("email"));
details.setPhone(obj.getString("phone"));
// ADD NEW DATA TO NEW LIST
mListNewItems.add(details);
} catch (JSONException e) {
e.printStackTrace();
}
// IMPORTANT TASK SHOULD DONE HERE
// Get Old Size Of the List before adding new data to notify new inserted items
int oldSize=mList.getSize();
// here we check whether we have such a data in our list. if we had, we dnt add that, otherwise add new data to our list
for (int i=0;i<mListNewItems.size();i++){
if(!mList.contain(mListNewItems.get(i))){
mList.add(mListNewItems.get(i));
}
}
//check how many new items added
int numberOfNewItems=mList.getSize()-oldSize;
// Here you should use notifyItemRangeInserted instead of notifyDataSetChange as it is less time consuming than notifyDataSetChange and also it let you to show animation for new added items.
adapter.notifyItemRangeInserted(oldSize,numberOfNewItems);
}