notifyDataSetChanged 后 Android ListView 不刷新 [英] Android ListView not refreshing after notifyDataSetChanged
问题描述
我的ListFragment代码
My ListFragment code
public class ItemFragment extends ListFragment {
private DatabaseHandler dbHelper;
private static final String TITLE = "Items";
private static final String LOG_TAG = "debugger";
private ItemAdapter adapter;
private List<Item> items;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.item_fragment_list, container, false);
return view;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.setHasOptionsMenu(true);
super.onCreate(savedInstanceState);
getActivity().setTitle(TITLE);
dbHelper = new DatabaseHandler(getActivity());
items = dbHelper.getItems();
adapter = new ItemAdapter(getActivity().getApplicationContext(), items);
this.setListAdapter(adapter);
}
@Override
public void onResume() {
super.onResume();
items.clear();
items = dbHelper.getItems(); //reload the items from database
adapter.notifyDataSetChanged();
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
if(dbHelper != null) { //item is edited
Item item = (Item) this.getListAdapter().getItem(position);
Intent intent = new Intent(getActivity(), AddItemActivity.class);
intent.putExtra(IntentConstants.ITEM, item);
startActivity(intent);
}
}
}
我的列表视图
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
但这不会刷新ListView
.即使在重新启动应用程序后,也不会显示更新的项目.我的 ItemAdapter
扩展了 BaseAdapter
But this does not refresh the ListView
. Even after restarting app the updated items are not shown. My ItemAdapter
extends BaseAdapter
public class ItemAdapter extends BaseAdapter{
private LayoutInflater inflater;
private List<Item> items;
private Context context;
public ProjectListItemAdapter(Context context, List<Item> items) {
super();
inflater = LayoutInflater.from(context);
this.context = context;
this.items = items;
}
@Override
public int getCount() {
return items.size();
}
@Override
public Object getItem(int position) {
return items.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ItemViewHolder holder = null;
if(convertView == null) {
holder = new ItemViewHolder();
convertView = inflater.inflate(R.layout.list_item, parent,false);
holder.itemName = (TextView) convertView.findViewById(R.id.topText);
holder.itemLocation = (TextView) convertView.findViewById(R.id.bottomText);
convertView.setTag(holder);
} else {
holder = (ItemViewHolder) convertView.getTag();
}
holder.itemName.setText("Name: " + items.get(position).getName());
holder.itemLocation.setText("Location: " + items.get(position).getLocation());
if(position % 2 == 0) {
convertView.setBackgroundColor(context.getResources().getColor(R.color.evenRowColor));
} else {
convertView.setBackgroundColor(context.getResources().getColor(R.color.oddRowColor));
}
return convertView;
}
private static class ItemViewHolder {
TextView itemName;
TextView itemLocation;
}
}
有人可以帮忙吗?
推荐答案
看看你在ItemFragment
中的onResume
方法:
@Override
public void onResume() {
super.onResume();
items.clear();
items = dbHelper.getItems(); // reload the items from database
adapter.notifyDataSetChanged();
}
您在调用 notifyDataSetChanged()
之前刚刚更新的不是适配器的字段 private List
但是片段的相同声明的字段.适配器仍然存储对您在创建适配器时传递的项目列表的引用(例如在片段的 onCreate 中).使您的代码按预期运行的最短(就更改数量而言)但并不优雅的方法就是简单地替换该行:
what you just have updated before calling notifyDataSetChanged()
is not the adapter's field private List<Item> items;
but the identically declared field of the fragment. The adapter still stores a reference to list of items you passed when you created the adapter (e.g. in fragment's onCreate).
The shortest (in sense of number of changes) but not elegant way to make your code behave as you expect is simply to replace the line:
items = dbHelper.getItems(); // reload the items from database
与
items.addAll(dbHelper.getItems()); // reload the items from database
更优雅的解决方案:
1) 删除项目 private List
来自 ItemFragment
- 我们只需要在适配器中保持对它们的引用
1) remove items private List<Item> items;
from ItemFragment
- we need to keep reference to them only in adapter
2) 将 onCreate 更改为:
2) change onCreate to :
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setHasOptionsMenu(true);
getActivity().setTitle(TITLE);
dbHelper = new DatabaseHandler(getActivity());
adapter = new ItemAdapter(getActivity(), dbHelper.getItems());
setListAdapter(adapter);
}
3) 在 ItemAdapter 中添加方法:
3) add method in ItemAdapter:
public void swapItems(List<Item> items) {
this.items = items;
notifyDataSetChanged();
}
4) 将您的 onResume 更改为:
4) change your onResume to:
@Override
public void onResume() {
super.onResume();
adapter.swapItems(dbHelper.getItems());
}
这篇关于notifyDataSetChanged 后 Android ListView 不刷新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!