我正在使用自定义ListView
,当我转到上一个活动并再次访问ListViewActivity时,它会在数量上加倍(重复listItems)。
我可以看到问题发生的地方。当我第一次进入ListViewActivity时,一切都很好,其中列表项被添加到ArrayList
并且适配器已设置。但是,当我转到上一个活动并再次访问ListViewActivity时,先前设置的列表项仍然存在于Adapter
中,并且当进程通过setAdapter()
时,再次设置列表项,这会导致重复列表项目。
我遇到了许多解决方案,例如使用notifyDataSetChanged()
,清除ArrayList
,setAdapter(null)
等。这些解决方案都没有帮助我。
我想解决方法是清除Adapter
和ArrayList
并刷新Adapter
。但我不知道如何以及在何处完成它。
这是我的代码:
这是LoadingActivity.java中的数据接收类
private class CategoriesAsyncTask extends AsyncTask<String,Integer,Double>{
String res="";
String curState ="";
String httppoststr="";
boolean isNxtActivity=false;
@Override
protected Double doInBackground(String... params) {
// TODO Auto-generated method stub
postData(params[0]);
return null;
}
protected void onPostExecute(Double Result)
{
if(isNxtActivity)
{
Intent intent = new Intent(LoadingActivity.this, ListItemsActivity.class);
if(curState.equals(Constants.STATE_GET_STOCK_ITEMS))
{
intent.putStringArrayListExtra(Constants.STOCK_ITEMS_LIST, listOfItems);
intent.putExtra("curState", Constants.STATE_GET_STOCK_ITEMS);
intent.putExtra(Constants.CATEGORY_ID, categoryId);
intent.putExtra(Constants.CUSTOMER_ID, customerId);
LoadingActivity.this.startActivity(intent);
}
}
}
public void postData(String ValueIWantToSend) {
// Create a new HttpClient and Post Header
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(Constants.GatewayUrl);
try
{
JSONObject json = new JSONObject(ValueIWantToSend);
curState = json.getString("curState");
StringEntity se = new StringEntity(ValueIWantToSend);
httppost.setEntity(se);
httppost.setHeader("Accept", "application/json");
httppost.setHeader("Content-type", "application/json");
httppoststr =httppost.toString();
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
res = EntityUtils.toString(entity, "UTF-8");
JSONObject jsonobj = new JSONObject(res);
String state = jsonobj.getString(Constants.STATE);
if(Constants.RESPONSE_SUCCESS.equals(state.toLowerCase()))
{
isNxtActivity =true;
if(curState.equals(Constants.STATE_GET_STOCK_ITEMS))
{
JSONArray itemsListJsonArray=new JSONArray();
itemsListJsonArray=jsonobj.getJSONArray(Constants.STOCK_ITEMS_LIST);
for(int i=0;i<itemsListJsonArray.length();i++)
{
String itemslist=itemsListJsonArray.getString(i);
listOfItems.add(itemslist.toString());
}
}
}
}
catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
catch (JSONException e) {
e.printStackTrace();
}
}
}
ListViewActivity.java
private String[] arrayOfNames;
private String[] arrayOfImageUrls;
ArrayList<String> listOfNames = new ArrayList<String>();
ArrayList<String> listOfImageUrls = new ArrayList<String>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_items);
itemsList=(ListView) findViewById(R.id.itemsList);
Bundle extras = getIntent().getExtras();
listOfItems = extras.getStringArrayList(Constants.STOCK_ITEMS_LIST); //The duplication occurs here while getting the data from the LoadingActivity when visiting this activity for the second time.
arrayOfNames = new String[listOfNames.size()];
for(int i=0;i<listOfNames.size();i++)
{
arrayOfNames[i]=listOfNames.get(i);
}
arrayOfImageUrls = new String[listOfImageUrls.size()];
for(int i=0;i<listOfImageUrls.size();i++)
{
arrayOfImageUrls[i]=listOfImageUrls.get(i);
}
listItemadapter = new CustomListItemsAdapter(this, arrayOfNames, arrayOfImageUrls);
itemsList.setAdapter(listItemadapter);
}
CustomAdapter.java
public class CustomListItemsAdapter extends BaseAdapter{
private Context context;
private LayoutInflater inflater;
private String[] arrayOfNames;
public CustomListItemsAdapter(ListItemsActivity listItemsActivity, String[] itemsName) {
// TODO Auto-generated constructor stub
context=listItemsActivity;
arrayOfNames = itemsName;
inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return arrayOfNames.length;
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public static class ViewHolder
{
private TextView itemName;
private ImageView itemImage;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView==null)
{
holder=new ViewHolder();
convertView = inflater.inflate(R.layout.list_item_content, parent, false);
holder.itemName = (TextView) convertView.findViewById(R.id.itemName);
holder.itemImage = (ImageView) convertView.findViewById(R.id.itemImage);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
holder.itemName.setText(arrayOfNames[position]);
StrictMode.ThreadPolicy policy = new
StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(policy);
ListItemsAsyncTask listAsync = new ListItemsAsyncTask();
Drawable drawableIcon = listAsync.loadImageFromServer(arrayOfImageUrls[position]);
holder.itemImage.setImageDrawable(drawableIcon);
return convertView;
}
private class ListItemsAsyncTask extends AsyncTask<String, Integer, Double> {
String httpPostStr, res;
Boolean NextActivity = false;
public Drawable loadImageFromServer(String url)
{
try {
InputStream is = (InputStream) new URL(url).getContent();
Drawable drawable = Drawable.createFromStream(is, "src name");
return drawable;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
@Override
protected Double doInBackground(String... params) {
return null;
}
}
任何建议???
更新:我发现了这种重复背后的问题。第二次来到ListViewActivity时,复制发生在Bundle中,我从中获取ListView
及其内容的数据。
现在我需要一个解决方案来阻止Bundle中的重复。我在ListViewActivity.java
中提到了带有注释的重复出现行答案 0 :(得分:0)
在onCreate()中只调用函数 setAdapter()一次,因为仅在活动首次启动时调用onCreate(),第二次启动活动onCreate()时不调用on,但是如果你破坏了活动,那么将再次调用onCreate(),确保你没有破坏活动。
答案 1 :(得分:0)
可能您正在onResume
中加载列表,并且您要将项目添加到附加到适配器的列表中,并且每次都有重复项。
正确的方法是:
在onResume
中加载数据,确保在添加数据之前不要将重复项添加到列表或清除列表。然后在填充列表之后 - 检查适配器是否已初始化并附加(如果已经初始化),然后将数据添加到列表中,如果未初始化,则将简单生成适配器.notifyDataSetChanged()
,然后将列表附加到其上进行初始化。
当您将列表附加到适配器时请注意,然后您无法更改指向列表变量的指针:
yourList = downloadedList; // Wrong way you will override the pointer to list in adapter
必须是这样的:
yourList.clear();
yourList.addAll(downloadedList); // Correct way
adapter.notifyDataSetChanged();