LiveData
のコンストラクタのためのViewModel
があります。
LiveData<List<Book>> books;
public MyViewModel(@NonNull Application application) {
super(application);
books = bookRepository.getBooks();
}
ユーザーがUIから新しいbook
を作成すると、attribute book_order
を他の本のインクリメント最大book_order
で入力したいです。私が欲しいものをよりよく説明するには、次のプライドコードを参照してください。
book.book_order = max(books.book_order) + 1;
そのため、それぞれbook_order
1,2,3のブックがある場合は、新しい本がこの属性を4に設定します。
質問は、LiveData
in ViewModel
でこれを行うにはどうすればよいですか。 Transformations.map
を新しいLiveData
の使用を使用してみましたが、このアプローチはまったく機能していません、bookMax
はnull
のようです。
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
uiからアプリロジックを分離するために作成されました。しかし、この場合、価値を観察したいのであれば、私はActivity
にする必要があるため、そうするようには思われません。また、この種の方法をDBから1つの値を取得する方法はありませんでした。あらゆる助けがあります。
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
_
[〜#〜]編集[〜#〜]ここではJavaコード
_// 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);
_
マックス予約を見つけるためにすべての本を取得する代わりに、DBからのbook_order
の最大数を入力するようなリポジトリにメソッドを作成する必要があります。
疑似コード以下のようなもの:
int maxOrder = bookRepository.getMaxBookOrder();
さて、あなたが新しい本を挿入している間は、そのmaxOrder
変数をincremental目的に使用することができます。
それで、あなたの挿入方法は次のようになります。
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
その後、MAXを見つけてから1つずつ増加します。
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
から拡張することをお勧めします。
LiveDataを使用すると、シナリオには役立ちません。
[。] DAOのLiveDataが別のスレッドで実行され、新しい値がオブザーバーコードまたはCase Transformation.Map()コールバックで転記されます。そのため、transformation.map()内のbook.idにアクセスする必要があります。
[。]。ただし、Transformat.map()で本を挿入すると、すべてのテーブルエントリに更新されています。
だから、あなたの場合は: