在学习新的 android Architecture 组件的 ViewModel 和 LiveData 时,在观察 LiveData 随数据库源变化而变化时有点困惑,以及这如何与 Cursor 适配器一起工作。
在https://developer.android.com/reference/android/widget/CursorAdapter.html , 它说
int FLAG_REGISTER_CONTENT_OBSERVER
If set the adapter will register a content observer on the cursor
and will call onContentChanged() when a notification comes in. Be
careful when using this flag: you will need to unset the current
Cursor from the adapter to avoid leaks due to its registered
observers. This flag is not needed when using a CursorAdapter
with a CursorLoader.
因此使用 cursorAdaptor 它有一种方法可以在更新数据库数据时获得“实时更新”。
有没有办法通过 cursorAdaptor 使用 LiveData(观察数据库数据更新)?
试图在下面的代码 fragment 中展示在哪里使用 liveData 更新光标的问题: (样本为https://codelabs.developers.google.com/codelabs/android-persistence)
这本书:
@Entity
public class Book {
public @PrimaryKey String id;
public String title;
}
View 模型:
public class BooksBorrowedByUserViewModel extends AndroidViewModel {
public final LiveData<List<Book>> books;
private AppDatabase mDb;
public BooksBorrowedByUserViewModel(Application application) {
super(application);
createDb();
// Books is a LiveData object so updates are observed.
books = mDb.bookModel().findBooksBorrowedByName("Mike"); //<=== this ViewModel specific to one type query statement
}
public void createDb() {
mDb = AppDatabase.getInMemoryDatabase(this.getApplication());
// Populate it with initial data
DatabaseInitializer.populateAsync(mDb);
}
}
这是使用LiveData观察器强制重新加载游标的方式吗?
private CursorAdapter listAdapter;
private BooksBorrowedByUserViewModel mViewModel;
private void subscribeUiBooks() {
mViewModel.books.observe(this, new Observer<List<Book>>() {
@Override
public void onChanged(@NonNull final List<Book> books) {
showBooksInUi(books, mBooksTextView); //<== the sample’s code
// if would like to update the cursorAdaptor
//
// ??? to requery the database and swap cursor here?
// Cursor data = queryData(buildSqlStatement()); // build the same sql statement as used in the BooksBorrowedByUserViewModel
// listAdapter.swapCursor(data)
}
});
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//having a list using CursorAdaptor
ListView list = getListView();
listAdapter = new CursorAdapter(getActivity(), null, 0)
list.setAdapter(listAdapter);
// Get a reference to the ViewModel for this screen.
mViewModel = ViewModelProviders.of(this).get(BooksBorrowedByUserViewModel.class);
subscribeUiBooks();
}
最佳答案
CursorAdapter 是老东西了,应该用 Room + LiveData + RecyclerView。
您的数据层:
public LiveData<List<UserEntity>> getUsers() {
return userDao.getUsers();
}
您的 Activity :
viewModel.getUsers().observe(this, new Observer<List<UserEntity>>() {
@Override
public void onChanged(@Nullable List<UserEntity> users) {
if (users != null) {
adapter.setUsers(users);
}
}
});
在适配器中:
private List<UserEntity> users = new ArrayList<>();
public void setUsers(List<UserEntity> users) {
this.users.clear();
this.users.addAll(users);
notifyDataSetChanged();
}
因此,当您的 Activity 午餐时,您应该从 Room 获取实时数据并订阅它。之后,当您向该表添加内容时,room 会自动更新观察者,因此您只需向适配器设置新数据并通知它即可。
关于android - 如何使用新的系统架构ViewModel/LiveData with cursorAdapter?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45636997/