Patroy
Patroy

Reputation: 377

How to set fixed quantity of items in GridView Widget?

I have GridView widget which is populated by 40 images taken from ArrayList, problem is when widget is trying to load more positions than 40 and it makes about few hundreds of blank cells with "loading" text. This wouldn't happen if number of items was fixed by 40, but how to do that?

enter image description here

This is my RemoteViewsFactory class:

public class WidgetRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {
    private Context ctx;
    private Cursor cursor;
    private ArrayList<Bitmap> photos = new ArrayList<>(40);

    public WidgetRemoteViewsFactory(Context applicationContext, Intent intent) {
        ctx = applicationContext;
    }

    @Override
    public void onCreate() {

    }

    @Override
    public void onDataSetChanged() {

        String[] projection = new String[]{
                MediaStore.Images.ImageColumns._ID,
                MediaStore.Images.ImageColumns.DATA,
                MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME,
                MediaStore.Images.ImageColumns.DATE_TAKEN,
                MediaStore.Images.ImageColumns.MIME_TYPE
        };
        cursor = ctx.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, null,
                null, MediaStore.Images.ImageColumns.DATE_TAKEN + " DESC");

        cursor.moveToFirst();
        for (int i = 1; i <= 39; i++) {
            Bitmap bmp = BitmapFactory.decodeFile(cursor.getString(1));
            photos.add(bmp);
            cursor.moveToNext();
            Log.d(TAG, "loop iteration" + i );
        }
    }


    @Override
    public void onDestroy() {
        if (cursor != null) {
            cursor.close();
        }
    }

    @Override
    public int getCount() {
        return cursor == null ? 0 : cursor.getCount();
    }

    @Override
    public RemoteViews getViewAt(int position) {
        if (position == AdapterView.INVALID_POSITION ||
                cursor == null || !cursor.moveToPosition(position) || photos == null || photos.size() == 0 || position >= photos.size()) {
            return null;
        }
            RemoteViews views = new RemoteViews(ctx.getPackageName(), R.layout.widget_item);
            Bitmap img = resizeBitmapFitXY(250, 150, photos.get(position));
            views.setImageViewBitmap(R.id.imageView, img);
            return views;
    }

    @Override
    public RemoteViews getLoadingView() {
        return null;
    }

    @Override
    public int getViewTypeCount() {
        return 1;
    }

    @Override
    public long getItemId(int position) {
        return cursor.moveToPosition(position) ? cursor.getLong(0) : position;
    }

    @Override
    public boolean hasStableIds() {
        return true;
    }





    public Bitmap resizeBitmapFitXY(int width, int height, Bitmap bitmap){
        Bitmap background = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        float originalWidth = bitmap.getWidth(), originalHeight = bitmap.getHeight();
        Canvas canvas = new Canvas(background);
        float scale, xTranslation = 0.0f, yTranslation = 0.0f;
        if (originalWidth > originalHeight) {
            scale = height/originalHeight;
            xTranslation = (width - originalWidth * scale)/2.0f;
        }
        else {
            scale = width / originalWidth;
            yTranslation = (height - originalHeight * scale)/2.0f;
        }
        Matrix transformation = new Matrix();
        transformation.postTranslate(xTranslation, yTranslation);
        transformation.preScale(scale, scale);
        Paint paint = new Paint();
        paint.setFilterBitmap(true);
        canvas.drawBitmap(bitmap, transformation, paint);
        return background;
    }
}

Upvotes: 1

Views: 80

Answers (1)

Ali Asadi
Ali Asadi

Reputation: 987

you need to replace this code

        cursor.moveToFirst();
        for (int i = 1; i <= 39; i++) {
            Bitmap bmp = BitmapFactory.decodeFile(cursor.getString(1));
            photos.add(bmp);
            cursor.moveToNext();
            Log.d(TAG, "loop iteration" + i );
        }

and put this instead

          if (cursor!=null && cursor.getCount()>0) {
                while (cursor.moveToNext()) {
                    Bitmap bmp = BitmapFactory.decodeFile(cursor.getString(1));
                    photos.add(bmp);
                    Log.d(TAG, "loop iteration" + i );
                }
            }

the problem that you used a fixed size in the for loop for (int i = 1; i <= 39; i++)

and the solution is to use while() loop to get all the item from the cursor and add it to your list


update answer after the comment :

Q: if you decide in the loop to load only 40 and not to load the blank text

you must to do this

 @Override
    public int getCount() {
        return 40;
    }

Upvotes: 1

Related Questions