我在LiveData
的构造函数中有ViewModel
for books:
LiveData<List<Book>> books;
public MyViewModel(@NonNull Application application) {
super(application);
books = bookRepository.getBooks();
}
当用户从UI创建新的book
时,我希望属性book_order
填充其他书籍的book_order
增量最大值。为了更好地描述我想要的内容,请参阅以下preudocode:
book.book_order = max(books.book_order) + 1;
因此,当有三本书分别使用book_order
1,2,3时,新书将此属性设置为4。
问题是,我怎么能在qazxsw poi中用qazxsw poi做到这一点?我尝试使用qazxsw poi到新的LiveData
,但这种方法根本不起作用,ViewModel
似乎是Transformations.map
。
LiveData
任何想法如何设置增量最大值到新书?它可以是另一种方法,而不是这里描述的方法。创建bookMax
是为了将应用程序逻辑与UI分开。然而,在这种情况下似乎没有这样做,因为如果我想观察价值,我需要在null
。另外,我没有找到任何替代方法如何从DB获取一个值。任何帮助赞赏。
请注意,你的qazxsw poi是qazxsw poi,这可能会不时改变它的价值。
哪里你的public void insertBook(Book book) {
LiveData<Integer> bookMax = Transformations.map(books,
list -> {
int value = 0;
for(Book b: list) {
if (value < b.getBookOrder()) {
value = b.getBookOrder();
}
}
}
);
book.setBookOrder(bookMax + 1)
bookRepository.update(book);
}
是一个值,应该在插入时计算。
要插入你需要:
ViewModel
编辑这是Java代码
Activity
使用LiveData对您的方案没有帮助。 DAO中的LiveData在不同的线程上执行,新值在观察者代码或您的情况下发布Transformation.map()回调。因此,您需要访问Transformation.map()中的book.id. 但是,如果您在Transformation.map()中插入book,它将触发无限循环,因为在每个表条目更新时,将调用Transformation.map(),因为LiveData>将更改。
所以,对于你的情况:
您应该在存储库中创建一个方法,从而为db提供最大数量的books
,而不是将所有书籍都用于查找最大订单量。
像下面的伪代码:
livedata
现在,您需要做的就是在插入新书时,可以将bookMax
变量用于增量目的。
所以,你的插入方法将是:
val bookList: List<Book> = books.value // current value. may be null!
val bookMax: Int = bookList.maxBy { it.order }.order // find max order
// insert
val newBooks = arrayListOf(bookList)
newBooks.add(newBook)
books.value = newBooks // update your livedata
在这里,假设您使用ROOM来持久化数据库,这是可以帮助您获得最大// get current value. may be null!
List<Book> bookList = books.getValue();
// so we better handle it early
if (bookList == null) {
bookList = new ArrayList<>();
}
// calculate max order
int maxOrder = -1;
for (Book book : bookList) {
if (maxOrder < book.order) {
maxOrder = book.order;
}
}
// create new book
Book newBook = new Book();
newBook.order = maxOrder + 1;
// add book to the list
bookList.add(newBook);
// do with new list whatever you want
// for example, you can update live data (if it is a MutableLiveData)
books.setValue(bookList);
的查询:
book_order
如果ROOM不是你的情况那么,你可以采用另一种方法:
我们首先使用存储库方法检索列表,然后从中找到最大值,如下面的伪:
int maxOrder = bookRepository.getMaxBookOrder();
然后从中找到max,然后将其递增1:
maxOrder
即使你可以将这个查找最大值的代码移动到前面提到的存储库方法,例如:
public void insertBook(Book book) {
int maxOrder = bookRepository.getMaxBookOrder();
book.setBookOrder(maxOrder + 1)
bookRepository.update(book);
}
如果你真的想用book_order
来做,你可以创建一个自定义的:
SELECT MAX(book_order) FROM Book
然后你可以创建它并使用:
List<Book> books = bookRepository.getBooks().getValue(); // Assuming getBooks() returns LiveData
您仍然可以观察到这些实时数据,因为它在添加图书时发布了public void insertBook(Book book) {
List<Book> books = bookRepository.getBooks().getValue();
// calculating max order using loop
int maxOrder = -1;
for (Book book : books) {
if (maxOrder < book.order) {
maxOrder = book.order;
}
}
book.setBookOrder(maxOrder + 1)
bookRepository.update(book);
}
,它会通知观察者。您可以更改它,例如,返回已添加的书等。
旁注:从public int getMaxBookOrder() {
List<Book> books = getBooks().getValue();
// calculating max order using loop
int maxOrder = -1;
for (Book book : books) {
if (maxOrder < book.order) {
maxOrder = book.order;
}
}
return maxOrder;
}
延伸可能更好,因为LiveData
不应该更新它的值,但在内部你发布的东西,所以它可能会令人困惑。
方法1:您可以使用自动增量字段或class BooksLiveData(list: List<Book>) : LiveData<List<Book>>() {
val initialList: MutableList<Book> = list.toMutableList()
fun addBook(book: Book) {
with(initialList) {
// Assuming your list is ordered
add(book.copy(last().bookOrder + 1))
}
postValue(initialList)
}
}
(例如val data = bookRepository.getBooks() // Make getBooks() return BooksLiveData now
data.addBook(userCreatedBook) // This'll trigger observers as well
)来获取initialList
的功能。如果你愿意,你甚至可以将它命名为MutableLiveData
。使您的模型或实体类像:
LiveData
这样,PrimaryKey
在添加到数据库的每个id
上都会增加。
接下来你可以得到你的qazxsw poi类:
book_order
现在,您可以通过在活动的book_order
中调用以下方法,将您的列表活动订阅到此ViewModel(即让您的活动观察ViewModel):
public class Book{
@PrimaryKey(autoGenerate = true)
private int book_order;
//other data members, constructors and methods
}
做这些事情,你将能够收到更新,即。每当用户将book_order
添加到您的数据库时,List / Recycler视图应自动显示新添加的Book
。
方法2:如果这不是你想要的,你只想找到最新添加的书的顺序,你可以完全跳过第三个代码块并在ViewModel
中使用以下代码:
public class MyViewModel extends AndroidViewModel {
private BookRepository bookRepository;
LiveData<List<Book>> books;
public MyViewModel(@NonNull Application application) {
super(application);
bookRepository = AppRepository.getInstance(application.getApplicationContext());
books = bookRepository.getBooks();
}
}
它给出了书籍的总数。 books表中的行,然后可以从存储库调用,而这些行又可以从ViewModel调用,而ViewModel又可以从Activity调用。
方法3:如果你想要添加新书后我认为是数据库中最新书籍数量的onCreate()
,你可以使用方法1,它在ViewModel中提供了Book of Book。然后,您可以从书单中获取书籍数量。
重要!无论哪种方式,您都希望在编辑器或newBook ViewModel中编辑private void initViewModel() {
final Observer<List<Book>> bookObserver= new Observer<List<Book>>() {
@Override
public void onChanged(@Nullable List<Book> books) {
bookList.clear();
bookList.addAll(books);
if (mAdapter == null) {
mAdapter = new BooksAdapter(bookList, YourActivity.this);
mRecyclerView.setAdapter(mAdapter);
} else {
mAdapter.notifyDataSetChanged();
}
}
};
mViewModel = ViewModelProviders.of(this)
.get(MyViewModel.class);
mViewModel.mBooks.observe(this, notesObserver); //mBooks is member variable in ViewModel class
}
方法,并使其类似于:
Book
并在您的存储库对应的插入看起来像:
Book
和相应的Dao方法:
Dao