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?
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;
}
}
答案 0 :(得分:1)
您需要替换此代码
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 );
}
并将其改为
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 );
}
}
在for循环中使用固定大小的问题
for (int i = 1; i <= 39; i++)
和解决方案是使用
while()
循环来获取光标中的所有项目并将其添加到列表中
评论后更新答案:
问:如果您决定在循环中仅加载40而不加载空白文本
你必须这样做
@Override
public int getCount() {
return 40;
}