blob: 740083eaa9d59562084c6f9a6eaefee15e779867 [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package io.v.baku.toolkit.bind;
import android.support.annotation.IdRes;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ListView;
import io.v.baku.toolkit.BakuActivityTrait;
import java8.util.function.Function;
import rx.Observable;
/**
* Collection bindings are read-only bindings from Syncbase data to collections of UI elements, such
* as items in a {@link ListView} or {@link RecyclerView}. In addition to defining the Syncbase data
* being mapped, collection bindings are responsible for ordering/arranging the data and mapping
* them to their view elements (they are Android widget adapters). Writes are generally done through
* {@linkplain BakuActivityTrait#getSyncbaseTable() direct database writes}.
*/
public abstract class CollectionBindingBuilder<B extends CollectionBindingBuilder<B, T, A>,
T, A extends RangeAdapter> extends DerivedBindingBuilder<B, BindingBuilder> {
public CollectionBindingBuilder(final BindingBuilder base) {
super(base);
}
private ViewAdapter<? super T, ?> mViewAdapter;
public B viewAdapter(
final ViewAdapter<? super T, ?> viewAdapter) {
mViewAdapter = viewAdapter;
return mSelf;
}
public B textViewAdapter() {
return viewAdapter(new TextViewAdapter(mBase.getDefaultViewAdapterContext()));
}
public B textViewAdapter(final Function<T, ?> fn) {
return viewAdapter(new TextViewAdapter(mBase.getDefaultViewAdapterContext()).map(fn));
}
protected ViewAdapter<? super T, ?> getDefaultViewAdapter() {
return new TextViewAdapter(mBase.getDefaultViewAdapterContext());
}
private ViewAdapter<? super T, ?> getViewAdapter() {
return mViewAdapter == null ? getDefaultViewAdapter() : mViewAdapter;
}
private <U extends RangeAdapter> U subscribeAdapter(final U adapter) {
mBase.subscribe(adapter.getSubscription());
return adapter;
}
public abstract Observable<? extends ListAccumulator<T>> buildListAccumulator();
public abstract Observable<? extends ListDeltaAccumulator<T>> buildListDeltaAccumulator();
public RxListAdapter<T> buildListAdapter() {
return subscribeAdapter(new RxListAdapter<>(
buildListAccumulator(), getViewAdapter(), mBase.mOnError));
}
public RxRecyclerAdapter<T, ?> buildRecyclerAdapter() {
return subscribeAdapter(new RxRecyclerAdapter<>(
buildListDeltaAccumulator(), getViewAdapter(), mBase.mOnError));
}
public RxListAdapter<T> bindTo(final ListView listView) {
final RxListAdapter<T> adapter = buildListAdapter();
listView.setAdapter(adapter);
return adapter;
}
public RxRecyclerAdapter<T, ?> bindTo(final RecyclerView recyclerView) {
final RxRecyclerAdapter<T, ?> adapter = buildRecyclerAdapter();
recyclerView.setAdapter(adapter);
return adapter;
}
public RangeAdapter bindTo(final View view) {
if (view instanceof ListView) {
return bindTo((ListView) view);
} else if (view instanceof RecyclerView) {
return bindTo((RecyclerView) view);
} else {
throw new IllegalArgumentException("No default binding for view " + view);
}
}
/**
* Binds to the view identified by {@code viewId}.
* @see #bindTo(View)
*/
public RangeAdapter bindTo(final @IdRes int viewId) {
return bindTo(mBase.mActivity.findViewById(viewId));
}
}