/*
* Copyright (c) 2015 OpenSilk Productions LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package syncthing.android.ui.common;
import android.databinding.OnRebindCallback;
import android.databinding.ViewDataBinding;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.List;
import timber.log.Timber;
/**
* Created by drew on 3/10/15.
*/
public abstract class CardRecyclerAdapter extends RecyclerView.Adapter<CardViewHolder> {
protected ExpandableView.OnExpandListener mExpandListener;
protected RecyclerView mRecyclerView;
protected LayoutInflater mLayoutInflater;
public CardRecyclerAdapter() {
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
mRecyclerView = recyclerView;
mExpandListener = (ExpandableView.OnExpandListener) mRecyclerView;
mLayoutInflater = LayoutInflater.from(recyclerView.getContext());
}
@Override
public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
mRecyclerView = null;
mExpandListener = null;
mLayoutInflater = null;
}
public abstract Card getItem(int pos);
public android.databinding.DataBindingComponent getBindingComponent(){
return null;
}
@Override
public final CardViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final View v = mLayoutInflater.inflate(viewType, parent, false);
final CardViewHolder viewHolder;
if (getBindingComponent() != null) {
viewHolder = new CardViewHolder(v, getBindingComponent());
} else {
viewHolder = new CardViewHolder(v);
}
//Trick from the databinding talk by google
viewHolder.getBinding().addOnRebindCallback(new OnRebindCallback() {
@Override
public boolean onPreBind(ViewDataBinding binding) {
return mRecyclerView != null && mRecyclerView.isComputingLayout();
}
@Override
public void onCanceled(ViewDataBinding binding) {
if (mRecyclerView == null || mRecyclerView.isComputingLayout()) {
return;
}
int position = mRecyclerView.getChildAdapterPosition(binding.getRoot());
if (position != RecyclerView.NO_POSITION) {
notifyItemChanged(position, DATA_INVALIDATION);
}
}
});
return viewHolder;
}
public void applyAdditionalBinding(Card card, CardViewHolder holder) {
}
@Override
public void onBindViewHolder(CardViewHolder holder, int position) {
holder.recycle();
Card c = getItem(position);
holder.bind(c, mExpandListener);
applyAdditionalBinding(c, holder);
}
@Override
public void onBindViewHolder(CardViewHolder holder, int position, List<Object> payloads) {
if (isForDataBinding(payloads)) {
Timber.d("executing pending binding for %d", position);
holder.getBinding().executePendingBindings();
} else {
super.onBindViewHolder(holder, position, payloads);
}
}
@Override
public int getItemViewType(int pos) {
Card c = getItem(pos);
return c.getLayout();
}
@Override
public void onViewRecycled(CardViewHolder holder) {
holder.recycle();
}
private static final Object DATA_INVALIDATION = new Object();
private static boolean isForDataBinding(List<Object> payloads) {
if (payloads == null || payloads.isEmpty()) {
return false;
}
for (Object obj : payloads) {
if (obj != DATA_INVALIDATION) {
return false;
}
}
return true;
}
}