_Android.databinding.ObservableList
_の実際の存在理由をデータバインディング機能として見つけるのは難しいと思います。
最初は data binding を通じてリストを表示し、xml
を介してRecyclerView
にリストを追加するためのクールなツールのように見えました。そうするために、私は BindingAdapter を次のように作成しました:
_@BindingAdapter(value = {"items"}, requireAll = false)
public static void setMyAdapterItems(RecyclerView view, ObservableList <T> items) {
if(items != null && (view.getAdapter() instanceof MyAdapter)) {
((GenericAdapter<T>) view.getAdapter()).setItems(items);
}
}
_
このように、RecyclerView
に設定されたMyAdapter
で属性_app:items
_を使用して、その項目を更新できます。
これで、ObservableList
の最も優れた機能は、OnListChangedCallback
を追加できることです。これにより、RecyclerView
で使用可能な同じイベントを処理して、リスト全体を実際に再読み込みせずに、アイテムを追加/移動/削除/変更できます。
したがって、私が実装しようと思ったロジックは、次のようなものです。
MyAdapter
から始めますObservableArrayList
をインスタンス化してそれらをラップし、binding
に渡しますBindingAdapter
が呼び出され、アイテムがMyAdapter
に渡されますMyAdapter
が新しいアイテムを受け取ると、古いアイテムをクリアし、受け取ったOnListChangedCallback
にObservableList
を追加して、マイクロ変更を処理しますObservableList
で何かが変更されると、MyAdapter
は完全に更新されずにそれに応じて変更されますbinding
変数を再設定するだけでよいので、BindingAdapter
が再度呼び出され、MyAdapter
項目が完全に変更されます。たとえば、「所有ゲーム」と「ウィッシュリストゲーム」の2つの異なるリストがあるGame
タイプのアイテムを表示する場合、binding.setItems(whateverItems)
を呼び出すだけで表示アイテムを完全に更新できますが、たとえば、「ウィッシュリストゲーム」をリスト内で移動して関連性で整理すると、各リスト内でマイクロ変更のみが実行され、全体が更新されることはありません。
BindingAdapter
に1つの変更が加えられるたびにデータバインディングがObservableList
を再実行するため、このアイデアは実現不可能であることがわかります。たとえば、次のような動作が見られます。
MyAdapter
から始めますObservableArrayList
をインスタンス化してそれらをラップし、binding
に渡しますBindingAdapter
が呼び出され、アイテムがMyAdapter
に渡されますMyAdapter
が新しいアイテムを受け取ると、古いアイテムをクリアし、受け取ったOnListChangedCallback
にObservableList
を追加して、マイクロ変更を処理しますObservableList
で何かが変更されると、BindingAdapter
が再度呼び出されるため、MyAdapter
はリスト全体を再度受け取り、完全に更新されます。ObservableList
がデータバインドされたxml
内で使用できないようにするため、この動作は私にはかなり壊れているようです。この振る舞いが望ましい正当なケースを真剣に理解することはできません。
私はいくつかの例を調べました: here および this other SO question
最初のリンクでは、すべての例でObservableList
を直接Adapter
に使用しましたが、フォームxml
および実際のデータバインディングを渡さなくても、SO回答でリンクされたコードでは、開発者は基本的に同じことを行いました私はやろうとしました:
_if (this.items == items){
return;
}
_
ObservableList
の単純な変更のためにメソッドが呼び出されるすべてのケースを破棄するために、彼のAdapter.setItems(ObservableList<T> items)
の先頭に。
この動作の必要性は何ですか?この動作が望ましいいくつかのケースは何でしょうか? ObservableList
はデータバインディングで追加された機能であり、実際のデータバインディングで使用する場合を除いて本当に便利です。その場合、その動作から保護する必要があります。 List
データタグとxml
の両方のシグネチャで単純なBindingAdapter
として宣言すると、ObservableList
内のMyAdapter
にキャストバックでき、正常に機能しますが、これはかなり悪いハックです。それがデータバインディングとは別の機能であり、すべての変更でバインディングをトリガーしない場合、私の意見でははるかに優れていたでしょう。
ドキュメントで提供されている例によると https://developer.Android.com/topic/libraries/data-binding/index.html#observable_collections ObservableListは、キー整数を使用してアイテムにアクセスするために使用されます、つまり:
_<data>
<import type="Android.databinding.ObservableList"/>
<import type="com.example.my.app.Fields"/>
<variable name="user" type="ObservableList<Object>"/>
</data>
…
<TextView
Android:text='@{user[Fields.LAST_NAME]}'
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"/>
_
したがって、ObservableList
内で何かが変更されると、BindingAdapterがトリガーされてUIが更新されます。 DataBindingが開発状態にある間、これがObservableList
を使用する主な目的だと思います。おそらく将来的には、DataBindingはRecyclerViewで使用するための新しいSomeObservableList
で更新される予定です。その間、機能する場合はif (this.items == items){return;}
を使用するか、ObservableList
を使用するロジックを再検討できます。