我在使用AsyncTaskLoader
时遇到问题。这是我第一次尝试使用加载程序从 SQLite 数据库填充 ListView 。
一切似乎都没问题,当我旋转屏幕时,数据被缓存并且不再进行任何查询。但是当我按下主页按钮并再次启动我的应用程序时,数据会再次加载。
注意:Usuario
表示User
,因此我使用用户列表填充 ListView 。
public class Main extends SherlockFragmentActivity
implements LoaderManager.LoaderCallbacks<ArrayList<Usuario>> {
UsuarioAdapter adapter;
ListView listView;
Database db;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
listView = (ListView) findViewById(R.id.lista);
db = new Database(this);
adapter = new UsuarioAdapter(this, new ArrayList<Usuario>());
listView.setAdapter(adapter);
getSupportLoaderManager().initLoader(0, null, this);
}
@Override
public Loader<ArrayList<Usuario>> onCreateLoader(int id, Bundle args) {
return new UsuariosLoader(this, db);
}
@Override
public void onLoadFinished(Loader<ArrayList<Usuario>> loader,
ArrayList<Usuario> usuarios) {
//adapter.notifyDataSetChanged();
listView.setAdapter(new UsuarioAdapter(this, usuarios));
// ((BaseAdapter) listView.getAdapter()).notifyDataSetChanged();
}
@Override
public void onLoaderReset(Loader<ArrayList<Usuario>> loader) {
listView.setAdapter(null);
}
}
// THE LOADER
class UsuariosLoader extends AsyncTaskLoader<ArrayList<Usuario>> {
private ArrayList<Usuario> usuarios;
private Database db;
public UsuariosLoader(Context context, Database db) {
super(context);
this.db = db;
}
@Override
protected void onStartLoading() {
if (usuarios != null) {
deliverResult(usuarios); // Use the cache
}
forceLoad();
}
@Override
protected void onStopLoading() {
// The Loader is in a stopped state, so we should attempt to cancel the
// current load (if there is one).
cancelLoad();
}
@Override
public ArrayList<Usuario> loadInBackground() {
db.open(); // Query the database
ArrayList<Usuario> usuarios = db.getUsuarios();
db.close();
return usuarios;
}
@Override
public void deliverResult(ArrayList<Usuario> data) {
usuarios = data; // Caching
super.deliverResult(data);
}
@Override
protected void onReset() {
super.onReset();
// Stop the loader if it is currently running
onStopLoading();
// Get rid of our cache if it exists
usuarios = null;
}
@Override
public void onCanceled(ArrayList<Usuario> data) {
// Attempt to cancel the current async load
super.onCanceled(data);
usuarios = null;
}
}
我觉得这个片段做得不好。我正在创建一个新的适配器,而不是更新数据。
@Override
public void onLoadFinished(Loader<ArrayList<Usuario>> loader,
ArrayList<Usuario> usuarios) {
//adapter.notifyDataSetChanged();
listView.setAdapter(new UsuarioAdapter(this, usuarios));
//((BaseAdapter) listView.getAdapter()).notifyDataSetChanged();
}
为什么adapter.notifyDataSetChanged()
不起作用?
所以,基本上,我的应用程序不会崩溃,但每次重新启动应用程序时,我的所有数据都会重新加载。
修改:这是我的适配器代码:
class UsuarioAdapter extends BaseAdapter {
private ArrayList<Usuario> usuarios;
private LayoutInflater inflater;
public UsuarioAdapter(Context context, ArrayList<Usuario> usuarios) {
this.usuarios = usuarios;
this.inflater = LayoutInflater.from(context);
}
@Override
public int getCount() { return usuarios.size(); }
@Override
public Object getItem(int pos) { return usuarios.get(pos); }
@Override
public long getItemId(int pos) { return pos; }
@Override
public View getView(int pos, View convertView, ViewGroup arg) {
LinearLayout itemView;
if (convertView == null) {
itemView = (LinearLayout) inflater.inflate(R.layout.list_item, null);
} else {
itemView = (LinearLayout) convertView;
}
ImageView avatar = (ImageView) itemView.findViewById(R.id.avatar);
TextView nombre = (TextView) itemView.findViewById(R.id.nombre);
TextView edad = (TextView)itemView.findViewById(R.id.edad);
// Set the image ... TODO
nombre.setText(usuarios.get(pos).getNombre());
edad.setText(String.valueOf(usuarios.get(pos).getEdad()));
return itemView;
}
}
答案 0 :(得分:3)
对notifyDataSetChanged()
的调用不会更改适配器正在使用的数据。您需要更新适配器具有的数据,然后调用该方法。
NotifyDataSetChanged()
只会告诉适配器创建视图所需的适配器,但它不会更改数据。你需要自己处理。
在适配器中添加:
public void setUsuario(List<Usuario> usuarios) {
this.usuarios = usuarios;
}
然后在onLoadFinished()
中调用新方法,然后notifyDataSetChanged()
。
listView.getAdapter().setUsuario(usuarios);
listView.getAdapter().notifiyDataSetChanged();
答案 1 :(得分:2)
我找到了解决方案。 onStartLoading
是有罪的:
@Override
protected void onStartLoading() {
if (usuarios != null) {
deliverResult(usuarios); // Use cache
} else {
forceLoad();
}
}
我的原始帖子forceLoad
总是被调用。它必须位于else
分支。