我有一个每分钟同步数据的服务。修改/创建数据时,我会向"活动"发送一个广播,以便更新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
方法。
所以我是根据我的问题来做这件事的,但你不会喜欢的。在我看来,最好的方法是使用CursorAdapter
和CursorLoader
来刷新数据库中的内容。所以你基本上不必做这项工作。一旦你从网络上获得信息并更新了数据库,你只需刷新适配器,新的信息就会反映出来。在您的情况下,如果不知道ListView
中的任何内容属于何处,则无法更改它。但用我刚才告诉你的方法,ListView
的setAdapter()
可以容纳CursorAdapter
,你可以刷新它。但这需要一些代码的重新编写。