package me.tatarka.bindingcollectionadapter2;
import android.databinding.DataBindingUtil;
import android.databinding.ObservableList;
import android.databinding.ViewDataBinding;
import android.support.annotation.LayoutRes;
import android.support.annotation.Nullable;
import android.support.v4.view.PagerAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.lang.ref.WeakReference;
import java.util.List;
/**
* A {@link PagerAdapter} that binds items to layouts using the given {@link ItemView} or {@link
* ItemViewSelector}. If you give it an {@link ObservableList} it will also updated itself based on
* changes to that list.
*/
public class BindingViewPagerAdapter<T> extends PagerAdapter implements BindingCollectionAdapter<T> {
private ItemBinding<T> itemBinding;
private final WeakReferenceOnListChangedCallback<T> callback = new WeakReferenceOnListChangedCallback<>(this);
private List<T> items;
private LayoutInflater inflater;
private PageTitles<T> pageTitles;
@Override
public void setItemBinding(ItemBinding<T> itemBinding) {
this.itemBinding = itemBinding;
}
@Override
public ItemBinding<T> getItemBinding() {
return itemBinding;
}
@Override
public void setItems(@Nullable List<T> items) {
if (this.items == items) {
return;
}
if (this.items instanceof ObservableList) {
((ObservableList<T>) this.items).removeOnListChangedCallback(callback);
}
if (items instanceof ObservableList) {
((ObservableList<T>) items).addOnListChangedCallback(callback);
}
this.items = items;
notifyDataSetChanged();
}
@Override
public T getAdapterItem(int position) {
return items.get(position);
}
@Override
public ViewDataBinding onCreateBinding(LayoutInflater inflater, @LayoutRes int layoutRes, ViewGroup viewGroup) {
return DataBindingUtil.inflate(inflater, layoutRes, viewGroup, false);
}
@Override
public void onBindBinding(ViewDataBinding binding, int variableId, @LayoutRes int layoutRes, int position, T item) {
if (itemBinding.bind(binding, item)) {
binding.executePendingBindings();
}
}
/**
* Sets the page titles for the adapter.
*/
public void setPageTitles(@Nullable PageTitles<T> pageTitles) {
this.pageTitles = pageTitles;
}
@Override
public int getCount() {
return items == null ? 0 : items.size();
}
@Override
public CharSequence getPageTitle(int position) {
return pageTitles == null ? null : pageTitles.getPageTitle(position, items.get(position));
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
if (inflater == null) {
inflater = LayoutInflater.from(container.getContext());
}
T item = items.get(position);
itemBinding.onItemBind(position, item);
ViewDataBinding binding = onCreateBinding(inflater, itemBinding.layoutRes(), container);
onBindBinding(binding, itemBinding.variableId(), itemBinding.layoutRes(), position, item);
container.addView(binding.getRoot());
binding.getRoot().setTag(item);
return binding.getRoot();
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@SuppressWarnings("unchecked")
@Override
public int getItemPosition(Object object) {
T item = (T) ((View) object).getTag();
if (items != null) {
for (int i = 0; i < items.size(); i++) {
if (item == items.get(i)) {
return i;
}
}
}
return POSITION_NONE;
}
private static class WeakReferenceOnListChangedCallback<T> extends ObservableList.OnListChangedCallback<ObservableList<T>> {
final WeakReference<BindingViewPagerAdapter<T>> adapterRef;
WeakReferenceOnListChangedCallback(BindingViewPagerAdapter<T> adapter) {
this.adapterRef = new WeakReference<>(adapter);
}
@Override
public void onChanged(ObservableList sender) {
BindingViewPagerAdapter<T> adapter = adapterRef.get();
if (adapter == null) {
return;
}
Utils.ensureChangeOnMainThread();
adapter.notifyDataSetChanged();
}
@Override
public void onItemRangeChanged(ObservableList sender, int positionStart, int itemCount) {
onChanged(sender);
}
@Override
public void onItemRangeInserted(ObservableList sender, int positionStart, int itemCount) {
onChanged(sender);
}
@Override
public void onItemRangeMoved(ObservableList sender, int fromPosition, int toPosition, int itemCount) {
onChanged(sender);
}
@Override
public void onItemRangeRemoved(ObservableList sender, int positionStart, int itemCount) {
onChanged(sender);
}
}
public interface PageTitles<T> {
CharSequence getPageTitle(int position, T item);
}
}