/*
* Copyright (c) 2015 Zhang Hai <Dreaming.in.Code.ZH@Gmail.com>
* All Rights Reserved.
*/
package me.zhanghai.android.douya.ui;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import butterknife.BindView;
import butterknife.ButterKnife;
import me.zhanghai.android.douya.R;
import me.zhanghai.android.douya.util.ViewUtils;
public class LoadMoreAdapter extends MergeAdapter {
private LoadMoreViewAdapter mViewAdapter;
public LoadMoreAdapter(int loadMoreLayoutRes, RecyclerView.Adapter<?>... adapters) {
super(mergeAdapters(adapters, new LoadMoreViewAdapter(loadMoreLayoutRes)));
adapters = getAdapters();
mViewAdapter = (LoadMoreViewAdapter) adapters[adapters.length - 1];
mViewAdapter.setParentAdapter(this);
}
private static RecyclerView.Adapter<?>[] mergeAdapters(RecyclerView.Adapter<?>[] adapters,
RecyclerView.Adapter<?> adapter) {
RecyclerView.Adapter<?>[] mergedAdapters = new RecyclerView.Adapter<?>[adapters.length + 1];
System.arraycopy(adapters, 0, mergedAdapters, 0, adapters.length);
mergedAdapters[adapters.length] = adapter;
return mergedAdapters;
}
public boolean isProgressVisible() {
return mViewAdapter.isProgressVisible();
}
public void setProgressVisible(boolean progressVisible) {
mViewAdapter.setProgressVisible(progressVisible);
}
static class LoadMoreViewAdapter extends RecyclerView.Adapter<LoadMoreViewAdapter.ViewHolder> {
private int mLoadMoreLayoutRes;
private boolean mShowingItem;
private ViewHolder mViewHolder;
private boolean mProgressVisible;
public LoadMoreViewAdapter(int loadMoreLayoutResId) {
mLoadMoreLayoutRes = loadMoreLayoutResId;
setHasStableIds(true);
}
// We need to postpone this until the super call of our parent is completed.
public void setParentAdapter(final LoadMoreAdapter parentAdapter) {
setShowingItem(parentAdapter.getItemCount() > 0);
parentAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
@Override
public void onItemRangeChanged(int positionStart, int itemCount) {
onChanged();
}
@Override
public void onItemRangeInserted(int positionStart, int itemCount) {
onChanged();
}
@Override
public void onItemRangeRemoved(int positionStart, int itemCount) {
onChanged();
}
@Override
public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
onChanged();
}
@Override
public void onChanged() {
// Don't show the progress item if our parent is empty - or else this can lead
// to incorrect scrolling position when items are added (before us).
setShowingItem(parentAdapter.getItemCount() > 0);
}
});
}
public void setShowingItem(boolean showingItem) {
if (mShowingItem == showingItem) {
return;
}
mShowingItem = showingItem;
if (mShowingItem) {
notifyItemInserted(0);
} else {
notifyItemRemoved(0);
}
}
public boolean isProgressVisible() {
return mProgressVisible;
}
public void setProgressVisible(boolean progressVisible) {
if (mProgressVisible == progressVisible) {
return;
}
mProgressVisible = progressVisible;
if (mShowingItem) {
if (mViewHolder != null) {
onBindViewHolder(mViewHolder, 0);
} else {
notifyItemChanged(0);
}
}
}
@Override
public int getItemCount() {
return mShowingItem ? 1 : 0;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ViewHolder holder = new ViewHolder(ViewUtils.inflate(mLoadMoreLayoutRes, parent));
ViewGroup.LayoutParams layoutParams = holder.itemView.getLayoutParams();
if (layoutParams instanceof StaggeredGridLayoutManager.LayoutParams) {
StaggeredGridLayoutManager.LayoutParams staggeredGridLayoutParams =
(StaggeredGridLayoutManager.LayoutParams) layoutParams;
staggeredGridLayoutParams.setFullSpan(true);
}
return holder;
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
ViewUtils.setVisibleOrInvisible(holder.progress, mProgressVisible);
mViewHolder = holder;
}
@Override
public void onViewRecycled(ViewHolder holder) {
mViewHolder = null;
}
static class ViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.progress)
public ProgressBar progress;
public ViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
}
}