我有一个自定义适配器,可视化订单列表中的每一行。
public class OrderRowAdapter extends BaseAdapter implements OnClickListener {
OrderList items_;
LayoutInflater inflater_;
int list_view_resource_id_;
private final String TAG = "OrderRowAdapter";
public OrderRowAdapter(Context context, int list_view_resource_id,
OrderList items) {
this.list_view_resource_id_ = list_view_resource_id;
this.items_ = items;
this.inflater_ = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public Object getItem(int position) {
return items_.getOrders(position);
}
public View getView(int position, View convertView, ViewGroup parent) {
Log.d(TAG, "View updated for item in position = " + position);
View v = convertView;
if (v == null) {
v = inflater_.inflate(list_view_resource_id_, parent);
}
Order item = items_.getOrders(position);
if (item != null) {
TextView order_info_tv = (TextView) v.findViewById(R.id.order_info);
TextView order_status_tv = (TextView) v.findViewById(R.id.order_status);
if (order_info_tv != null) {
order_info_tv.setText(
String.format("For customer: %s\nTotal of %d items", item.getCustomerId(), item.getItemsCount()));
}
if (order_status_tv != null) {
order_status_tv.setText("Status: " + getStatusText(item.getStatus()));
}
}
return v;
}
public int getCount() {
if (items_ == null) {
Log.d(TAG, "Null so get count returned 0");
return 0;
} else {
Log.d(TAG, "Get count returned " + items_.getOrdersCount());
return items_.getOrdersCount();
}
};
从Web服务查询新的订单列表后,我想更新ListView的内容,所以我让Activity在调用notifyDataSetChanged()之前进行更新
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.orders);
initThreading();
findViews();
setUrls();
// Load the list of order from disk
try {
order_list_ = OrderList.parseFrom(new FileInputStream(
"/sdcard/orderList.bin"));
} catch (FileNotFoundException e) {
Log.e(TAG, "Cannot find the file", e);
} catch (IOException e) {
Log.e(TAG, "Cannot read the file", e);
}
order_row_adapter_ = new OrderRowAdapter(OrderActivity.this,
R.layout.order_row, order_list_);
orders_listview_.setAdapter(order_row_adapter_);
// Request new updates from the server
updateOrderInformation(-1);
}
public void updateOrders(InputStream new_order_stream) {
Log.d(TAG, "Updating order UI");
try {
order_list_.parseFrom(new_order_stream);
} catch (IOException e) {
Log.e(TAG, "IOException" , e);
}
runOnUiThread(new Runnable() {
public void run() {
guiUpdateOrders();
}
});
}
private void guiUpdateOrders() {
order_row_adapter_.notifyDataSetChanged();
Log.d(TAG, "Dataset notified that it has changed. GUI update anytime now.");
}
但是,从不调用OrderRowAdapter的getView()方法。 ListView永远不会更新。
答案 0 :(得分:12)
事实证明我的getView()
未被调用的问题是因为它不可见。我的布局xml的高度为TextView
,fill_parent
为高度。因此,整个视图只能看到单个TextView
。
解决方案:检查相关布局的图形视图,确保ListView
可见。
答案 1 :(得分:4)
确保BaseAdapter
方法
registerDataSetObserver(DataSetObserver observer)
unregisterDataSetObserver(DataSetObserver observer)
没有被覆盖。
答案 2 :(得分:1)
要更改ListView的内容,必须对List使用相同的引用。在这里,您要创建另一个列表并将其分配给items_
变量(不包含列表本身,它只是存储对List的引用的位置),但您的View仍然引用旧的列表。
而不是items_ = new_order_list
这应该有效:
items_.clear();
items_.addAll(new_order_list);
编辑:
为了更好地解释它,尝试创建一个名为old_items
的新变量:
public void setNewOrderList(List<Order> new_order_list)
{
Log.d(TAG, "New Order List available. Num items = " + new_order_list.size());
List<Order> old_items = items_; // store the reference to the old list
items_ = new_order_list;
Log.d(TAG, "items_.size() = " + items_.size());
Log.d(TAG, "old_items.size() = " + old_items.size()); // The old list still exists, and it's the one used by your ListView
notifyDataSetChanged();
}
答案 3 :(得分:0)
如果以上所有答案都无效,请尝试使用invalidateViews()
ListView.invalidateViews()用于告诉ListView使其所有子项视图无效(重绘它们)。
请注意,不需要与项目相同数量的视图。这是因为ListView会回滚其项目视图,并在您滚动时以智能方式在屏幕上移动它们。
listView.invalidateViews()
我的示例实现,
lvitems.post(new Runnable() {
@Override
public void run() {
lvitems.invalidateViews(); //invalidate old
CustomAdapter customAdapter=new CustomAdapter(context, names, images); // load new data
customAdapter.notifyDataSetChanged();// call notifydatasetChanged
}
});
如果这个答案有任何错误,请纠正我的错误。