/*
* Copyright 2011 Azwan Adli Abdullah
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.gh4a.fragment;
import android.os.Bundle;
import android.support.v4.content.Loader;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import com.gh4a.PageIteratorWithSaveableState;
import com.gh4a.R;
import com.gh4a.adapter.RootAdapter;
import com.gh4a.loader.LoaderCallbacks;
import com.gh4a.loader.LoaderResult;
import com.gh4a.loader.PageIteratorLoader;
import org.eclipse.egit.github.core.client.PageIterator;
import java.util.ArrayList;
import java.util.Collection;
public abstract class PagedDataBaseFragment<T> extends LoadingListFragmentBase implements
RootAdapter.OnItemClickListener<T>, RootAdapter.OnScrolledToFooterListener {
private RootAdapter<T, ? extends RecyclerView.ViewHolder> mAdapter;
private PageIteratorWithSaveableState<T> mIterator;
private boolean mIsLoadCompleted;
private View mLoadingView;
private static final String STATE_KEY_ITERATOR_STATE = "iterator_state";
private final LoaderCallbacks<PageIteratorLoader<T>.LoadedPage> mLoaderCallback =
new LoaderCallbacks<PageIteratorLoader<T>.LoadedPage>(this) {
@Override
protected Loader<LoaderResult<PageIteratorLoader<T>.LoadedPage>> onCreateLoader() {
return new PageIteratorLoader<>(getActivity(), mIterator);
}
@Override
protected void onResultReady(PageIteratorLoader<T>.LoadedPage result) {
fillData(result.results, result.hasMoreData);
mIsLoadCompleted = true;
setContentShown(true);
mAdapter.notifyDataSetChanged();
updateEmptyState();
}
};
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setContentShown(false);
mIterator = (PageIteratorWithSaveableState<T>) onCreateIterator();
if (savedInstanceState != null) {
mIterator.restoreState(savedInstanceState.getBundle(STATE_KEY_ITERATOR_STATE));
}
getLoaderManager().initLoader(0, null, mLoaderCallback);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (mIterator != null) {
outState.putBundle(STATE_KEY_ITERATOR_STATE, mIterator.saveState());
}
}
@Override
public void onRefresh() {
if (mAdapter != null) {
mAdapter.clear();
}
mIsLoadCompleted = false;
hideContentAndRestartLoaders(0);
}
@Override
protected void onRecyclerViewInflated(RecyclerView view, LayoutInflater inflater) {
super.onRecyclerViewInflated(view, inflater);
mAdapter = onCreateAdapter();
mLoadingView = inflater.inflate(R.layout.list_loading_view, view, false);
mAdapter.setFooterView(mLoadingView, this);
mAdapter.setOnItemClickListener(this);
view.setAdapter(mAdapter);
updateEmptyState();
}
@Override
protected boolean hasDividers() {
return !mAdapter.isCardStyle();
}
@Override
protected boolean hasCards() {
return mAdapter.isCardStyle();
}
private void fillData(Collection<T> data, boolean hasMoreData) {
mLoadingView.setVisibility(hasMoreData ? View.VISIBLE : View.GONE);
if (mAdapter.getCount() > 0 && !data.isEmpty() && data.iterator().next() == mAdapter.getItem(0)) {
// there are common items, preserve them in order to keep the scroll position
ArrayList<T> newData = new ArrayList<>();
int index = 0, count = mAdapter.getCount();
for (T item : data) {
if (index < count && item == mAdapter.getItem(index++)) {
// we already know about the item
continue;
}
newData.add(item);
}
onAddData(mAdapter, newData);
} else {
mAdapter.clear();
onAddData(mAdapter, data);
}
}
protected void onAddData(RootAdapter<T, ? extends RecyclerView.ViewHolder> adapter, Collection<T> data) {
adapter.addAll(data);
}
@Override
public void onScrolledToFooter() {
if (mIsLoadCompleted && mLoadingView.getVisibility() == View.VISIBLE) {
mIsLoadCompleted = false;
getLoaderManager().getLoader(0).forceLoad();
}
}
protected abstract RootAdapter<T, ? extends RecyclerView.ViewHolder> onCreateAdapter();
protected abstract PageIterator<T> onCreateIterator();
public abstract void onItemClick(T item);
}