追記
- バージョンによっては動作しない。
- column_keyに_idが必要
- column数取得を実装する必要がある
- ContentProviderを別APKにすると、Cursor利用側でキャッシュがされる。
ScreenShot
Class
MainActivity-->MyAdapter (ItemLayout)<-->MyCursor<-->MyContentProvider
MainActivity
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ContentResolver cr = getContentResolver();
Uri uri = Uri.parse("content://com.example.test05");
Cursor cursor = cr.query(uri, null, null, null, null);
MyAdapter adapter = new MyAdapter(this, cursor, false);
ListView listView = (ListView)findViewById(R.id.listView);
listView.setAdapter(adapter);
}
}
MyAdapter
public class MyAdapter extends CursorAdapter {
private LayoutInflater mFactory;
public MyAdapter(Context context, Cursor c) {
super(context, c);
}
public MyAdapter(Context context, Cursor c, boolean autoRequery) {
super(context, c, autoRequery);
mFactory = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public MyAdapter(Context context, Cursor c, int flags) {
super(context, c, flags);
mFactory = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup viewGroup) {
ItemLayout view = (ItemLayout) mFactory.inflate(R.layout.item, viewGroup, false);
return view;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
ItemLayout v = (ItemLayout)view;
v.bindView(
cursor.getString(0),
cursor.getString(1),
cursor.getString(2)
);
}
}
MyCursor
public class MyCursor implements Cursor {
private List<Map<String, Object>> data;
private int pos = -1;
public MyCursor(List<Map<String, Object>> data) {
this.data = data;
}
@Override
public int getCount() {
return data.size();
}
@Override
public int getPosition() {
return pos;
}
@Override
public boolean move(int i) {
if (pos + i <= i && pos + i < getCount()) {
pos = pos + i;
return true;
}
return false;
}
@Override
public boolean moveToPosition(int i) {
Log.i("xxx", "MyCursor#moveToPosition pos=" + pos);
if (0 <= i && i < getCount()) {
pos = i;
return true;
}
return false;
}
@Override
public boolean moveToFirst() {
if (data == null || data.isEmpty()) {
return false;
}
pos = 0;
return true;
}
@Override
public boolean moveToLast() {
if (data == null || data.isEmpty()) {
return false;
}
pos = data.size() - 1;
return true;
}
@Override
public boolean moveToNext() {
Log.i("xxx", "MyCursor#moveToNext pos=" + pos);
if (data == null || pos >= data.size() - 1) {
return false;
}
pos++;
return true;
}
@Override
public boolean moveToPrevious() {
if (data == null || pos < 1) {
return false;
}
pos--;
return true;
}
@Override
public boolean isFirst() {
return pos == 0;
}
@Override
public boolean isLast() {
return pos == getCount();
}
@Override
public boolean isBeforeFirst() {
return pos == -1;
}
@Override
public boolean isAfterLast() {
return pos == data.size() - 1;
}
@Override
public int getColumnIndex(String s) {
return 0;
}
@Override
public int getColumnIndexOrThrow(String s) throws IllegalArgumentException {
return 0;
}
@Override
public String getColumnName(int i) {
return null;
}
@Override
public String[] getColumnNames() {
return new String[0];
}
@Override
public int getColumnCount() {
return 0;
}
@Override
public byte[] getBlob(int i) {
return new byte[0];
}
@Override
public String getString(int i) {
Map<String, Object> item = data.get(pos);
switch (i) {
case 0:
return String.valueOf(item.get("id"));
case 1:
return (String) item.get("name");
case 2:
return (String) item.get("address");
default:
throw new RuntimeException("invalid id " + i);
}
}
@Override
public void copyStringToBuffer(int i, CharArrayBuffer charArrayBuffer) {
}
@Override
public short getShort(int i) {
return 0;
}
@Override
public int getInt(int i) {
return 0;
}
@Override
public long getLong(int i) {
return 0;
}
@Override
public float getFloat(int i) {
return 0;
}
@Override
public double getDouble(int i) {
return 0;
}
@Override
public int getType(int i) {
return 0;
}
@Override
public boolean isNull(int i) {
return false;
}
@Override
public void deactivate() {
}
@Override
public boolean requery() {
return false;
}
@Override
public void close() {
Log.i("XXX", "close !");
}
@Override
public boolean isClosed() {
return false;
}
@Override
public void registerContentObserver(ContentObserver contentObserver) {
}
@Override
public void unregisterContentObserver(ContentObserver contentObserver) {
}
@Override
public void registerDataSetObserver(DataSetObserver dataSetObserver) {
}
@Override
public void unregisterDataSetObserver(DataSetObserver dataSetObserver) {
}
@Override
public void setNotificationUri(ContentResolver contentResolver, Uri uri) {
}
@Override
public Uri getNotificationUri() {
return null;
}
@Override
public boolean getWantsAllOnMoveCalls() {
return false;
}
@Override
public Bundle getExtras() {
return null;
}
@Override
public Bundle respond(Bundle bundle) {
return null;
}
}
MyContentProvider
public class MyContentProvider extends ContentProvider {
@Override
public boolean onCreate() {
Log.i("XXX", "onCreate");
return false;
}
@Override
public String getType(Uri uri) {
Log.i("XXX" , "getType:" + uri);
return null;
}
@Override
public Uri insert(Uri uri, ContentValues contentValues) {
Log.i("XXX" , "insert:" + uri + ", cv:" + contentValues);
return Uri.parse("insert");
}
@Override
public int delete(Uri uri, String s, String[] strings) {
Log.i("XXX" , "delete:" + uri);
return 1;
}
@Override
public int update(Uri uri, ContentValues contentValues, String s, String[] strings) {
Log.i("XXX" , "update:" + uri+ ", cv:" + contentValues);
return 2;
}
@Override
public Cursor query(Uri uri, String[] strings, String s, String[] strings2, String s2) {
Log.i("XXX" , "query:" + uri);
Cursor c = new MyCursor(getData());
return c;
}
private List<Map<String, Object>> getData() {
List<Map<String, Object>> ret = new ArrayList<Map<String, Object>>();
for (int i = 0; i < 1000; i++) {
ret.add(getItem(i));
}
return ret;
}
private Map<String, Object> getItem(int v) {
String str = nextSessionId();
Map<String, Object> m1 = new HashMap<String, Object>();
m1.put("id", v);
m1.put("name" , "name-" + v + "-" + str);
m1.put("address" , "address-" + v + "-" + str);
return m1;
}
private SecureRandom random = new SecureRandom();
public String nextSessionId() {
return new BigInteger(30, random).toString(32);
}
}
ItemLayout
public class ItemLayout extends LinearLayout {
private TextView tv1;
private TextView tv2;
private TextView tv3;
public ItemLayout(Context context) {
super(context);
}
public ItemLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ItemLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
tv1 = (TextView) findViewById(R.id.textView1);
tv2 = (TextView) findViewById(R.id.textView2);
tv3 = (TextView) findViewById(R.id.textView3);
}
public void bindView(String id, String name, String address) {
tv1.setText(id);
tv2.setText(name);
tv3.setText(address);
}
}
Activity Layout
xml version="1.0" encoding="utf-8"
<RelativeLayout xmlnsandroid="http://schemas.android.com/apk/res/android"
xmlnstools="http://schemas.android.com/tools"
androidlayout_width="match_parent"
androidlayout_height="match_parent"
androidpaddingBottom="@dimen/activity_vertical_margin"
androidpaddingLeft="@dimen/activity_horizontal_margin"
androidpaddingRight="@dimen/activity_horizontal_margin"
androidpaddingTop="@dimen/activity_vertical_margin"
toolscontext="com.example.test05.MainActivity">
<TextView
androidlayout_width="wrap_content"
androidlayout_height="40dp"
androidtext="CursorTest"
androidid="@+id/textView2"
androidtextStyle="bold"
androidtextSize="30sp"
androidtextColor="#2d3043"
androidlayout_alignParentStart="true" />
<ListView
androidlayout_width="wrap_content"
androidlayout_height="wrap_content"
androidid="@+id/listView"
androidlayout_below="@+id/textView2"
androidlayout_alignParentEnd="true" />
</RelativeLayout>
Item Layout
xml version="1.0" encoding="utf-8"
<comexampletest05ItemLayout xmlnsandroid="http://schemas.android.com/apk/res/android"
androidlayout_width="match_parent" androidlayout_height="50dp"
androidorientation="horizontal"
androidweightSum="1">
<TextView
androidid="@+id/textView1"
androidlayout_width="wrap_content"
androidlayout_height="match_parent"
androidbackground="#ffffff"
androidgravity="center"
androidtext="New Text1"
androidtypeface="monospace" />
<TextView
androidid="@+id/textView2"
androidlayout_width="86dp"
androidlayout_height="match_parent"
androidlayout_gravity="center_horizontal"
androidlayout_weight="0.26"
androidgravity="center"
androidtext="New Text2"
androidtypeface="monospace" />
<TextView
androidid="@+id/textView3"
androidlayout_width="wrap_content"
androidlayout_height="match_parent"
androidlayout_gravity="right"
androidlayout_weight="0.68"
androidgravity="center"
androidtext="New Text3"
androidtypeface="monospace" />
</comexampletest05ItemLayout>