web-dev-qa-db-ja.com

LiveDataから1つの値を入手してください

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の使用を使用してみましたが、このアプローチはまったく機能していません、bookMaxnullのようです。

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つの値を取得する方法はありませんでした。あらゆる助けがあります。

5
Tom11

bookslivedataです。このようにして変更時々その値。
[。] 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);
_
1
dhabensky

マックス予約を見つけるためにすべての本を取得する代わりに、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;
}
0
Jeel Vankhede

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から拡張することをお勧めします。

0
Mel

LiveDataを使用すると、シナリオには役立ちません。

[。] DAOのLiveDataが別のスレッドで実行され、新しい値がオブザーバーコードまたはCase Transformation.Map()コールバックで転記されます。そのため、transformation.map()内のbook.idにアクセスする必要があります。

[。]。ただし、Transformat.map()で本を挿入すると、すべてのテーブルエントリに更新されています。

だから、あなたの場合は:

  1. 最後の本IDを公開するメソッドを公開します
  2. 新しいエントリを挿入してください。
  3. UIの更新と表示を受け取るためのLiveData>を追加します。
0
Nilesh Tiwari