Skip to content

Instantly share code, notes, and snippets.

@b3er
Created April 3, 2013 15:38
Show Gist options
  • Save b3er/5302329 to your computer and use it in GitHub Desktop.
Save b3er/5302329 to your computer and use it in GitHub Desktop.
package fahrbot.apps.calculator.ui.widget;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import tiny.lib.log.L;
import tiny.lib.misc.ExFactory;
import tiny.lib.misc.app.IRenderer;
import tiny.lib.misc.utils.ExExecutor;
import tiny.lib.sorm.ex.ExDbAdapter;
import tiny.lib.sorm.ex.IExCursorCollection;
import tiny.lib.sorm.ex.collections.GroupingCursorView;
import java.util.concurrent.atomic.AtomicBoolean;
public class ExDbEndlessAdapter<T> extends ExDbAdapter<T> {
private final static String TAG = "ExDbEndlessAdapter";
AtomicBoolean mIsRequestPending;
private int mProvidedCount;
private int mPreloadStart = 15;
private int mRequestSizeMax = 50;
public ExDbEndlessAdapter(@NotNull Context context,
@Nullable IExCursorCollection<T> objects,
@NotNull IRenderer<T> renderer) {
super(context, objects, renderer);
init();
}
public ExDbEndlessAdapter(@NotNull Context context,
@Nullable IExCursorCollection<T> objects, int type,
@NotNull IRenderer<T> renderer) {
super(context, objects, type, renderer);
init();
}
private void init() {
mIsRequestPending = new AtomicBoolean(false);
mProvidedCount = mObjects != null ? mObjects.size() : 0;
}
public void setPreloadStart(int start) {
mPreloadStart = start;
}
public void setRequestSize(int requestSize) {
mRequestSizeMax = requestSize;
}
@Override
protected View getViewInternal(int position, View convertView, ViewGroup parent, int type) {
if (position + mPreloadStart >= mProvidedCount) {
postRequest();
}
return super.getViewInternal(position, convertView, parent, type);
}
private void postRequest() {
if (mObjects != null && !mIsRequestPending.get()) {
ExExecutor.runBackground(new Runnable() {
@Override
public void run() {
requestNew();
}
});
}
}
private void requestNew() {
if (mObjects instanceof IExCursorCollection && mIsRequestPending.compareAndSet(false, true)) {
mProvidedCount = mObjects.size();
int newSize = findNext(mProvidedCount, mRequestSizeMax);
if (newSize > 0) {
final int finalNewSize = newSize;
ExFactory.runOnUiThread(new Runnable() {
@Override
public void run() {
mProvidedCount += finalNewSize;
notifyDataSetChanged();
mIsRequestPending.set(false);
}
});
} else {
mIsRequestPending.set(false);
}
}
}
private int findNext(int provided, int offset) {
L.d(TAG, "findNext() provided: %s, offset: %s", provided, offset);
if (offset == 0) {
return 0;
} else if (mObjects.get(provided + offset - 1) != null) {
return offset;
}
return findNext(provided, offset / 2);
}
@Override
public void startUpdating() {
if (mObjects instanceof GroupingCursorView) {
((GroupingCursorView)mObjects).invalidate();
}
super.startUpdating();
}
@Override
public void onChanged() {
ExFactory.runOnUiThread(new Runnable() {
@Override
public void run() {
ExDbEndlessAdapter.super.onChanged();
}
});
}
@Override
public void onInvalidated() {
ExFactory.runOnUiThread(new Runnable() {
@Override
public void run() {
ExDbEndlessAdapter.super.onInvalidated();
}
});
}
/* From Adapter */
@Override
public T getItem(int position) {
//L.d(TAG, "getItem(%s)", position);
return super.getItem(position);
}
/* From IAdapterObserver */
@Override
public void notifyDataSetChanged() {
mObjects.get(mProvidedCount > 0 ? mProvidedCount - 1 : mPreloadStart);
mProvidedCount = mObjects.size();
super.notifyDataSetChanged();
}
/* From IExAdapter */
@Override
public int getCount() {
return mProvidedCount;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment