在不知道其位置的情况下删除listView中的项目(从广播意图的服务中)



我有一个每分钟同步数据的服务。修改/创建数据时,我会向"活动"发送一个广播,以便更新ListView。

为了更新视图,我想删除它并用正确的值重新创建,但我不知道它的位置,我只有它的textViews的内容。

活动:

public void onCreate{
...
this.registerReceiver(this.updateListReceiver, new IntentFilter(
            "com.android.updatelist"));
}
BroadcastReceiver updateListReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String id = intent.getExtras().getString("AccountId");
        String name = intent.getExtras().getString("AccountName");
        boolean isNew = intent.getExtras().getBoolean("isNew");
        if (isNew) {
            Account accountInList = new Account(id, name, null, null, null,
                    null);
            adapter.add(accountInList);
        } else {
        }
    }
};

服务:

Intent intent = new Intent();
                                intent.setAction("com.android.updatelist");
                                intent.putExtra("AccountId",
                                        updatedAccount.getAccountId());
                                intent.putExtra("AccountName",
                                        updatedAccount.getName());
                                intent.putExtra("isNew", true);
                                sendBroadcast(intent);

适配器:

public class AccountNameListAdapter extends ArrayAdapter<Account> {
private final Context context;
private final int layoutResourceId;
private final ArrayList<Account> data;
private final TableLayout table;
private final TextView tableName;
private final TextView tableIndustry;
private final TextView tablePhone;
private final TextView tableWebsite;
final AccountBDD accountBdd;
public AccountNameListAdapter(Context context, int layoutResourceId,
        ArrayList<Account> data) {
    super(context, layoutResourceId, data);
    this.layoutResourceId = layoutResourceId;
    this.context = context;
    this.data = data;
    table = (TableLayout) ((Activity) context)
            .findViewById(R.id.tableLayout);
    tableName = (TextView) ((Activity) context).findViewById(R.id.NameText);
    tableIndustry = (TextView) ((Activity) context)
            .findViewById(R.id.IndustryText);
    tablePhone = (TextView) ((Activity) context)
            .findViewById(R.id.PhoneText);
    tableWebsite = (TextView) ((Activity) context)
            .findViewById(R.id.WebsiteText);
    accountBdd = SQLiteApplication.getAccountBdd();
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    AccountHolder holder = null;
    if (convertView == null) {
        LayoutInflater inflater = ((Activity) context).getLayoutInflater();
        convertView = inflater.inflate(layoutResourceId, parent, false);
        holder = new AccountHolder();
        convertView.setClickable(true);
        convertView.setFocusable(true);
        holder.txtName = (TextView) convertView.findViewById(R.id.nom);
        holder.txtId = (TextView) convertView.findViewById(R.id.id);
        convertView.setTag(holder);
    } else {
        holder = (AccountHolder) convertView.getTag();
    }
    convertView.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            table.setVisibility(0);
            String id = data.get(position).getAccountId();
            Account displayAccount = accountBdd.getAccountWithAccountID(id);
            tableName.setText(displayAccount.getName());
            tableIndustry.setText(displayAccount.getIndustry());
            tablePhone.setText(displayAccount.getPhone());
            tableWebsite.setText(displayAccount.getWebsite());
        }
    });
    holder.txtName.setText(data.get(position).getName());
    holder.txtId.setText(data.get(position).getAccountId());
    ImageButton img = (ImageButton) convertView.findViewById(R.id.check);
    img.setTag(position);
    return convertView;
}
static class AccountHolder {
    TextView txtName;
    TextView txtId;
}

}

我该怎么办?

在适配器中创建一个方法,将account_id作为输入。它应该是这样的:

private void deleteData(int account_id) {
   for(int i=0; i<data.size(); i++) {
      //search for the id and delete it from the data
   }
   notifyDatasetChanged();
}

从你收到BroadcastReceiver的活动来看,只要调用这个方法就可以了。它比你想象的要快得多。

UPDATE:Account是一个对象。remove不能以这种方式工作,因为地址内存总是会更改。

尝试在数据中找到确切对象的位置,然后尝试data.remove(position)。类似于此,而不是getAccountByID(int accountid)实现此:

private int getPositionFromID(int accountid) {
   for(int i=0; i<data.size(); i++) {
       if(data.get(i).getAccountID() == accountID)
           return i; //if you have a match
   }
   return -1; //error code, that is not found
}

然后使用该位置来去除准确的斑点:

private void deleteData(int account_id) {
   int position = getPositionFromID(int accountid);
   if(position == -1) {
      //handle error
   } else {
      data.remove(position); 
      notifyDatasetChanged();
   }
}

给你!现在您有一个完整的复制粘贴示例!我已经做了很多次了,不需要搞砸CursorAdapter或类似的东西,纯硬编码的java。我确信这确实有效,如果它在您的示例中不起作用,我会建议您进行调试并确保一切正常,因为我猜您的代码还有其他问题,而不是适配器没有填充。

您不能在不知道任何项目的位置的情况下删除任何项目。

一个不可行但有效的解决方案是:在收到广播后,重新创建所有内容。这意味着,无论哪个零件正在更新,都要刷新该零件,然后用新值再次创建它。

例如:如果您的列表正在更新,请从列表中删除所有项目,然后添加所有新值,并在适配器上调用notifyDataSetChange方法。

所以我是根据我的问题来做这件事的,但你不会喜欢的。在我看来,最好的方法是使用CursorAdapterCursorLoader来刷新数据库中的内容。所以你基本上不必做这项工作。一旦你从网络上获得信息并更新了数据库,你只需刷新适配器,新的信息就会反映出来。在您的情况下,如果不知道ListView中的任何内容属于何处,则无法更改它。但用我刚才告诉你的方法,ListViewsetAdapter()可以容纳CursorAdapter,你可以刷新它。但这需要一些代码的重新编写。

最新更新