Android - ListView 在数据重新排序后未更新
Android - ListView not updating after data reordering
我成功地用 ContextMenu
和两个 MenuItem
实现了我的 ListActivity
:"Move up" 和 "Move down"。单击时,代码在两个对象之间交换列 order_id。
MainActivity.java
@Override
public boolean onContextItemSelected(MenuItem item) {
...
case CONTEXT_MENU_MOVE_UP:
datasource.moveCommandUp(command);
adapter.reOrder();
adapter.notifyDataSetChanged();
break;
case CONTEXT_MENU_MOVE_DOWN:
datasource.moveCommandDown(command);
adapter.reOrder();
adapter.notifyDataSetChanged();
break;
...
}
CustomAdapter.java
public class CustomAdapter extends ArrayAdapter<Command>{
ArrayList<Command> objects;
...
public void reOrder() {
Collections.sort(objects, new Comparator<Command>() {
public int compare(Command c1, Command c2) {
return c1.compareTo(c2);
}
});
}
}
Command.java
public class Command implements Comparable<Command> {
public long id;
public String name;
public Long order_id;
@Override
public int compareTo(Command c) {
return this.order_id.compareTo(c.order_id);
}
}
我可以看到 datasource.moveCommandUp(command)
和 datasource.moveCommandDown(command)
运行良好,因为如果我关闭并重新启动我的应用程序,列表将被排序并且两个对象被正确交换。
问题是我需要重启应用程序才能显示效果,点击"Move up"或"Move down"后没有任何变化。
怎么了?
根据 Christian 的回答进行编辑
我没有更新适配器的对象。我没有使用排序,而是调用了 getAllCommands(),这为我提供了新顺序的数组(重新启动项被排序的原因),然后我用新的对象重置了对象。现在列表视图更新,但如果我单击一个项目。我仍然得到前一个,即它触发前一个项目提供的操作。怎么了?
MainActivity.java
@Override
public boolean onContextItemSelected(MenuItem item) {
...
case CONTEXT_MENU_MOVE_UP:
datasource.moveCommandUp(command);
values = datasource.getAllCommands();
adapter.setObjects(values);
break;
case CONTEXT_MENU_MOVE_DOWN:
datasource.moveCommandDown(command);
values = datasource.getAllCommands();
adapter.setObjects(values);
break;
...
}
CustomAdapter.java
public class CustomAdapter extends ArrayAdapter<Command>{
ArrayList<Command> objects;
...
public void setObjects(ArrayList<Command> newObjects) {
objects = newObjects;
notifyDataSetChanged();
}
}
编辑 2
正在使用
final Command command = adapter.getItem(position);
而不是
final Command command = (Command) getListAdapter().getItem(position);
问题解决了!
即使您删除了设置对象数组的适配器部分,看起来您正在使用数据库的内容初始化对象数组,在 reorder() 中您对对象数组进行排序,但是您没有显示任何代码,其中对象数组是从数据库重新加载的。您可以在 notifyDataSetChanged() 之前在适配器中执行此操作。
我成功地用 ContextMenu
和两个 MenuItem
实现了我的 ListActivity
:"Move up" 和 "Move down"。单击时,代码在两个对象之间交换列 order_id。
MainActivity.java
@Override
public boolean onContextItemSelected(MenuItem item) {
...
case CONTEXT_MENU_MOVE_UP:
datasource.moveCommandUp(command);
adapter.reOrder();
adapter.notifyDataSetChanged();
break;
case CONTEXT_MENU_MOVE_DOWN:
datasource.moveCommandDown(command);
adapter.reOrder();
adapter.notifyDataSetChanged();
break;
...
}
CustomAdapter.java
public class CustomAdapter extends ArrayAdapter<Command>{
ArrayList<Command> objects;
...
public void reOrder() {
Collections.sort(objects, new Comparator<Command>() {
public int compare(Command c1, Command c2) {
return c1.compareTo(c2);
}
});
}
}
Command.java
public class Command implements Comparable<Command> {
public long id;
public String name;
public Long order_id;
@Override
public int compareTo(Command c) {
return this.order_id.compareTo(c.order_id);
}
}
我可以看到 datasource.moveCommandUp(command)
和 datasource.moveCommandDown(command)
运行良好,因为如果我关闭并重新启动我的应用程序,列表将被排序并且两个对象被正确交换。
问题是我需要重启应用程序才能显示效果,点击"Move up"或"Move down"后没有任何变化。
怎么了?
根据 Christian 的回答进行编辑
我没有更新适配器的对象。我没有使用排序,而是调用了 getAllCommands(),这为我提供了新顺序的数组(重新启动项被排序的原因),然后我用新的对象重置了对象。现在列表视图更新,但如果我单击一个项目。我仍然得到前一个,即它触发前一个项目提供的操作。怎么了?
MainActivity.java
@Override
public boolean onContextItemSelected(MenuItem item) {
...
case CONTEXT_MENU_MOVE_UP:
datasource.moveCommandUp(command);
values = datasource.getAllCommands();
adapter.setObjects(values);
break;
case CONTEXT_MENU_MOVE_DOWN:
datasource.moveCommandDown(command);
values = datasource.getAllCommands();
adapter.setObjects(values);
break;
...
}
CustomAdapter.java
public class CustomAdapter extends ArrayAdapter<Command>{
ArrayList<Command> objects;
...
public void setObjects(ArrayList<Command> newObjects) {
objects = newObjects;
notifyDataSetChanged();
}
}
编辑 2
正在使用
final Command command = adapter.getItem(position);
而不是
final Command command = (Command) getListAdapter().getItem(position);
问题解决了!
即使您删除了设置对象数组的适配器部分,看起来您正在使用数据库的内容初始化对象数组,在 reorder() 中您对对象数组进行排序,但是您没有显示任何代码,其中对象数组是从数据库重新加载的。您可以在 notifyDataSetChanged() 之前在适配器中执行此操作。