I'm writing a screen that displays a row's worth of information from a DB. Basically it's a Detail Fragment that represents information pertaining to one 'row' in a table. I want to understand the best practice for binding data from a cursor (one unique row from a table) to a layout of textviews, checkboxes, etc.
Is AdapterView the ticket?
@JoeMalin suggested:
Then write an adapter between a cursor and an array of text views.
Which boils down my question. What's the right way to hook a series of text views to a cursor?
If you want to do processing on some of the cursor data before you move it to the text views, then you're going beyond the adapter pattern, which assumes that "recasting" the form of a data structure to another data structure without any intermediate processing. The virtue of an adapter is that, for two data structures A and B linked by an adapter, it's assumed that B automatically changes whenever A changes.
Of course, you can redefine the idea of adapter to insert your own intermediate operation, such as converting dates, or you could make the conversion an aspect of the view that's displaying the data. I am guessing that the "processing" is really formatting, which you do for display purposes. That's an attribute of the text view, not the data; write something that extends text view and converts dates as needed. Then write an adapter between a cursor and an array of text views.
I recently implemented my own data adapter class that may be in the ball park.
public class NoteImageDataAdapter {
private final View mMainView;
private Cursor mCursor;
private ViewHolder holder;
private ContentObserver mContentObserver;
public static class ViewHolder {
public TextView title;
public TextView text;
public ImageView image;
}
public NoteImageDataAdapter(View mainView, Cursor c) {
if (mainView == null) {
throw new IllegalArgumentException("View mainView cannot be null");
}
if (c == null) {
throw new IllegalArgumentException("Cursor c cannot be null");
}
mMainView = mainView;
mCursor = c;
holder = new ViewHolder();
holder.title = (TextView) mMainView.findViewById(R.id.title);
holder.text = (TextView) mMainView.findViewById(R.id.text);
holder.image = (ImageView) mMainView.findViewById(R.id.myImageView);
mContentObserver = new ImageNoteContentObserver(new Handler());
mCursor.registerContentObserver(mContentObserver);
bindView();
}
class ImageNoteContentObserver extends ContentObserver {
public ImageNoteContentObserver(Handler handler) {
super(handler);
}
@Override
public boolean deliverSelfNotifications() {
return true;
}
@Override
public void onChange(boolean selfChange) {
Log.d("NoteImageDataAdapter", "ImageNoteContentObserver.onChange( "
+ selfChange + ")");
super.onChange(selfChange);
mCursor.requery();
bindView();
}
}
public void bindView() {
Log.d("NoteImageDataAdapter", "bindView");
mCursor.moveToFirst();
holder.text.setText(Note.getText(mCursor));
holder.title.setText(Note.getTitle(mCursor));
Uri imageUri = Note.getImageUri(mCursor);
if (imageUri != null) {
assignImage(holder.image, imageUri);
} else {
Drawable d = Note.getImageThumbnail(mCursor);
holder.image.setImageDrawable(d);
holder.image.setVisibility(View.VISIBLE);
}
}
private static final int MAX_IMAGE_PIXELS = 1024*512;
private void assignImage(ImageView imageView, Uri imageUri){
if (imageView != null && imageUri != null){
ContentResolver cr = imageView.getContext().getContentResolver();
Display display = ((WindowManager) imageView.getContext()
.getSystemService(Context.WINDOW_SERVICE))
.getDefaultDisplay();
int width = (int) (display.getWidth() * 0.9);
int height = (int) (display.getHeight() * 0.9);
int minSideLength = Math.min(height, width);
Bitmap b = Util.makeBitmap(minSideLength, MAX_IMAGE_PIXELS, imageUri, cr, false);
if (b == null){
b = Util.makeBitmap(minSideLength, MAX_IMAGE_PIXELS/2, imageUri, cr, false);
}
if (b != null){
imageView.setImageBitmap(b);
imageView.setAdjustViewBounds(true);
imageView.setVisibility(View.VISIBLE);
}
}
}
}
private NoteImageDataAdapter mAdapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.note_image_view_layout);
wireDataAdapter();
}
private void wireDataAdapter() {
final String[] COLUMNS = new String[] {
Note.Columns.TITLE,
Note.Columns.TEXT,
Note.Columns.IMAGE_URI,
Note.Columns.IMAGE_THUMBNAIL,
Note.Columns._ID };
// the uri for the note row
Uri contentUri = getIntent().getData();
Cursor cur = managedQuery(contentUri, COLUMNS, null, null, null);
View mainLayout = this.findViewById(R.id.noteImageViewLayout);
mAdapter = new NoteImageDataAdapter(mainLayout, cur);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With