android - 如何使用新的系统架构ViewModel/LiveData with cursorAdapter?

标签 android viewmodel android-cursoradapter android-livedata

在学习新的 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 会自动更新观察者,因此您只需向适配器设置新数据并通知它即可。

Guide to App Architecture

LiveData

Room

关于android - 如何使用新的系统架构ViewModel/LiveData with cursorAdapter?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45636997/

相关文章:

android - 应用程序 SQLite DB 存储在 Android 上的什么位置

android - 将矢量图标与应用程序 bundle 在一起以供离线访问

wpf - 从模型更新 ViewModel 中的属性的正确方法

android - 未获取 CACHED_NAME 的通话记录

android - 如何使用 Cursor Adapter 刷新 listView

android - 从游标适配器删除和更新值

android - React-Native/metadata.xml 给我一个 403 禁止

android - intellij IDEA - 创建Android应用程序失败

knockout.js - viewmodel .prototype .function vs self .function 在 View 模型中?

android - Mockito 不模拟存储库