Last active
January 12, 2024 18:00
-
-
Save koush/6f2b9ef007e82d67f7effacef9f34ea8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ArrayList<WeakReference<ContentObserver>> observers = new ArrayList<WeakReference<ContentObserver>>(); | |
public void loadCursor(final BetterCursorAdapter adapter, final Uri uri, final String[] projection, final String selection, final String[] selectionArgs, final String sortOrder) { | |
final FutureCallback<BetterCursorAdapter> callback = new FutureCallback<BetterCursorAdapter>() { | |
@Override | |
public void onCompleted(Exception e, BetterCursorAdapter result) { | |
if (e != null) | |
return; | |
View view = getView(); | |
if (view == null) | |
return; | |
getRecyclerView().setEmptyView(view.findViewById(R.id.empty)); | |
view.findViewById(R.id.loading).setVisibility(View.GONE); | |
onLoaded(); | |
} | |
}; | |
final ContentObserver observer = new ContentObserver(handler) { | |
@Override | |
public void onChange(boolean selfChange) { | |
super.onChange(selfChange); | |
if (getActivity() == null) | |
return; | |
adapter.changeCursor(getActivity(), uri, projection, selection, selectionArgs, sortOrder) | |
.setCallback(callback); | |
} | |
}; | |
getActivity().getContentResolver().registerContentObserver(uri, false, observer); | |
observers.add(new WeakReference<ContentObserver>(observer)); | |
adapter.changeCursor(getActivity(), uri, projection, selection, selectionArgs, sortOrder) | |
.setCallback(callback); | |
} | |
@Override | |
public void onDestroy() { | |
for (WeakReference<ContentObserver> ref: observers) { | |
ContentObserver observer = ref.get(); | |
if (observer != null) | |
getActivity().getContentResolver().unregisterContentObserver(observer); | |
} | |
super.onDestroy(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.koushikdutta.cast; | |
import android.Manifest; | |
import android.app.Activity; | |
import android.content.ContentResolver; | |
import android.content.ContentValues; | |
import android.content.pm.PackageManager; | |
import android.database.Cursor; | |
import android.database.DatabaseUtils; | |
import android.net.Uri; | |
import android.os.Build; | |
import android.os.Handler; | |
import android.os.Looper; | |
import android.support.v4.app.ActivityCompat; | |
import android.support.v4.content.ContextCompat; | |
import android.support.v7.widget.RecyclerView; | |
import android.view.View; | |
import android.view.ViewGroup; | |
import com.koushikdutta.async.future.Future; | |
import com.koushikdutta.async.future.HandlerFuture; | |
import java.util.ArrayList; | |
import java.util.List; | |
/** | |
* Created by koush on 3/2/14. | |
*/ | |
public abstract class BetterCursorAdapter extends RecyclerView.Adapter<BetterCursorAdapter.BetterCursorViewHolder> { | |
protected final Handler handler = new Handler(Looper.getMainLooper()); | |
ArrayList<ContentValues> currentItems = new ArrayList<>(); | |
OnItemClickListener onClick; | |
OnItemLongClickListener onLongClick; | |
private int cursorSet; | |
public ArrayList<ContentValues> getItems() { | |
return new ArrayList<>(currentItems); | |
} | |
@Override | |
public void onBindViewHolder(BetterCursorAdapter.BetterCursorViewHolder holder, int position) { | |
holder.values = currentItems.get(position); | |
holder.position = position; | |
holder.bind(holder, holder.values); | |
} | |
public ContentValues getItem(int position) { | |
return currentItems.get(position); | |
} | |
@Override | |
public abstract BetterCursorAdapter.BetterCursorViewHolder onCreateViewHolder(ViewGroup parent, int viewType); | |
@Override | |
public int getItemCount() { | |
return currentItems.size(); | |
} | |
public void clear() { | |
currentItems.clear(); | |
notifyDataSetChanged(); | |
} | |
public void addAll(List<ContentValues> add) { | |
currentItems.addAll(add); | |
notifyDataSetChanged(); | |
} | |
protected void flush(final int c, final ArrayList<ContentValues> values, final boolean clear) { | |
handler.post(new Runnable() { | |
@Override | |
public void run() { | |
if (c != cursorSet) | |
return; | |
if (clear) | |
clear(); | |
addAll(values); | |
} | |
}); | |
} | |
synchronized private void swapCursor(final Cursor c, final HandlerFuture<BetterCursorAdapter> ret, final Exception fe) { | |
final int currentCursor = ++this.cursorSet; | |
if (c == null) { | |
ret.setComplete(fe, this); | |
return; | |
} | |
new Thread() { | |
@Override | |
public void run() { | |
try { | |
ArrayList<ContentValues> values = new ArrayList<ContentValues>(); | |
while (currentCursor == cursorSet && c.moveToNext()) { | |
ContentValues cv = new ContentValues(); | |
DatabaseUtils.cursorRowToContentValues(c, cv); | |
values.add(cv); | |
} | |
flush(currentCursor, values, true); | |
} | |
catch (Exception e) { | |
// cursor can get closed | |
} | |
finally { | |
c.close(); | |
ret.setComplete(fe, BetterCursorAdapter.this); | |
} | |
} | |
}.start(); | |
} | |
public Future<BetterCursorAdapter> changeCursor(final Activity context, final Uri uri, final String[] projection, | |
final String selection, final String[] selectionArgs, final String sortOrder) { | |
final HandlerFuture<BetterCursorAdapter> ret = new HandlerFuture<BetterCursorAdapter>(); | |
final ContentResolver resolver = context.getContentResolver(); | |
new Thread() { | |
@Override | |
public void run() { | |
final Runnable query = new Runnable() { | |
@Override | |
public void run() { | |
Cursor c; | |
Exception ex; | |
try { | |
c = resolver.query(uri, projection, selection, selectionArgs, sortOrder); | |
if (c == null) | |
throw new Exception("cursor null"); | |
ex = null; | |
} | |
catch (Exception e) { | |
c = null; | |
ex = e; | |
} | |
final Cursor cursor = c; | |
final Exception fe = ex; | |
handler.post(new Runnable() { | |
@Override | |
public void run() { | |
swapCursor(cursor, ret, fe); | |
} | |
}); | |
} | |
}; | |
query.run(); | |
} | |
}.start(); | |
return ret; | |
} | |
public interface OnItemClickListener { | |
void onClick(View view, ContentValues values, int position); | |
} | |
public interface OnItemLongClickListener { | |
boolean onLongClick(View view, ContentValues values, int position); | |
} | |
public void setOnClickListener(OnItemClickListener listener) { | |
onClick = listener; | |
} | |
public void setOnLongClickListener(OnItemLongClickListener listener) { | |
onLongClick = listener; | |
} | |
public abstract class BetterCursorViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener { | |
ContentValues values; | |
int position; | |
public BetterCursorViewHolder(View itemView) { | |
super(itemView); | |
itemView.setOnClickListener(this); | |
} | |
@Override | |
public void onClick(View v) { | |
if (onClick != null) | |
onClick.onClick(v, values, position); | |
} | |
@Override | |
public boolean onLongClick(View v) { | |
if (onLongClick == null) | |
return false; | |
return onLongClick.onLongClick(v, values, position); | |
} | |
public abstract void bind(BetterCursorViewHolder holder, ContentValues values); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
https://github.com/Germanunkol/OgreOculusSample/blob/master/WTFP-LICENSE.txt |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment