Question

I have a problem with using cursor adapter on gridview which I used the cursor to load photos from the media store. I realized my newView and bindView got called completely. I mean assuming i have 500 photos, the newView also get called the same number of times.

Did I do anything wrong ? I thought it will only call when the cell was visible on the screen..

    public int taskA = 0;

public GalleryCursorAdapter(Context context, Cursor c) {
    super(context, c);
    // TODO Auto-generated constructor stub
}

@Override
public void bindView(View view, Context context, Cursor cursor) {
    // TODO Auto-generated method stub
    int index = cursor.getColumnIndex(MediaStore.Images.Media._ID);
    long id = cursor.getLong(index);

    Bundle idBundle = new Bundle();
    idBundle.putLong("id", id);

    Message msg = new Message();
    msg.setData(idBundle);

    ImageHandler imgHandler = new ImageHandler(context, (ImageView) view);
    imgHandler.sendMessage(msg);

    view.setTag(imgHandler);
    Log.w("task s",  " count");
}

@SuppressLint({ "NewApi", "NewApi" })
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
    // TODO Auto-generated method stub
    int index = cursor.getColumnIndex(MediaStore.Images.Media._ID);
    long id = cursor.getLong(index);

    ImageView iView = new ImageView(context);

    Bundle idBundle = new Bundle();
    idBundle.putLong("id", id);

    Message msg = new Message();
    msg.setData(idBundle);

    ImageHandler imgHandler = new ImageHandler(context, iView);
    imgHandler.sendMessage(msg);

    iView.setTag(imgHandler);
    taskA++;
    Log.w("task s", taskA+ " count");
    return iView;
}

static class ImageHandler extends Handler {

    private ImageView mView;
    private Context mContext;

    public ImageHandler(Context c, ImageView v) {
        mView = v;
        mContext = c;
    }

    @Override
    public void handleMessage(Message msg) {

        Bundle idBundle = msg.getData();

        Long id = idBundle.getLong("id");
        Bitmap image = MediaStore.Images.Thumbnails.getThumbnail(
                mContext.getContentResolver(), 
                id, 
                MediaStore.Images.Thumbnails.MICRO_KIND, 
                new Options());

        mView.setImageBitmap(image);
    }
}
Was it helpful?

Solution

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
    ImageView iView = new ImageView(context);
    iView.setLayoutParams(new GridView.LayoutParams(200, 200));
    taskA++;
    Log.w("task s", taskA+ " count");
    return iView;
}

note, i removed all the code that isn't supposed to be in newView (it should be in bindView) replace new GridView.LayoutParams(200, 200) with whatever height/width you need, don't use wrap content as your content is empty at the beginning, resulting in 0x0 pixels, so ALL of the ImageViews from your cursor fit into the GridView at once (thus newView and bindView get called for every view)

OTHER TIPS

I would simply extend BaseAdapter rather than Cursor Adapter and pass the fetched Data to the Adapter with a callback. Still you are not using any kind of different thread for the getThumbnail - the handler executes in the main thread and is only for updating the UI usually.

Also you should work with ViewHolders and the convertView to speed up the Grid-Speed.

I have something like this as BaseAdapter for every Adapter:

public abstract class MyBaseAdapter extends BaseAdapter {

protected LayoutInflater inflater;
protected Context context;

public TikBaseAdapter(Context context) {
    this.context = context;
    this.inflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

public final View getView(int position, View convertView, ViewGroup parent) {
    int type = getItemViewType(position);
    if (convertView == null) {
        convertView = newView(type, parent);
    }
    bindView(position, type, convertView);
    return convertView;
}

/** Create a new instance of a view for the specified {@code type}. */
public abstract View newView(int type, ViewGroup parent);

/** Bind the data for the specified {@code position} to the {@code view}. */
public abstract void bindView(int position, int type, View view);



}

My real Adapter overrides getItemViewType and then using switch-cases to inflate the correct layout - and work with viewHolders (view.setTag()) to speed up the scroll-performance. just use view.getTag() in the bindView method and then edit the View-Items.

From what I understood, you need to bind data to the View you have created. Like this:

public class ExampleCursorAdapter extends CursorAdapter {
public ExampleCursorAdapter(Context context, Cursor c) {
    super(context, c);
}

@Override
public void bindView(View view, Context context, Cursor cursor) {
    TextView summary = (TextView)view.findViewById(R.id.summary);
    summary.setText(cursor.getString(
            cursor.getColumnIndex(ExampleDB.KEY_EXAMPLE_SUMMARY)));
}

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
    LayoutInflater inflater = LayoutInflater.from(context);
    View v = inflater.inflate(R.layout.item, parent, false);
    bindView(v, context, cursor);
    return v;
}
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top