GridView OutOfMemory Bitmap - java

So i have the problem that my app is crashing because of OutOfMemory.
There are really good and a lot of solutions first my Adaptercode:
public class ImageAdapter extends BaseAdapter {
private Context mContext;
// Keep all Images in array
public Integer[] mThumbIds = {
R.drawable.accidentally_open_internet_explorer,
R.drawable.angry_shaking, R.drawable.are_you_fucking_kidding_me,
R.drawable.angry_with_pc,
R.drawable.sample_7, R.drawable.awkward_moment,
R.drawable.awkward_moment,
R.drawable.beer_guy,
R.drawable.beng,
R.drawable.accidentally_open_internet_explorer, R.drawable.boobs,
R.drawable.big_smile, R.drawable.cereal_guy,
R.drawable.challenge_accepted_drunk, R.drawable.challenge_accepted,
R.drawable.bad_pokerface, R.drawable.challenge_considered,
R.drawable.challenge_denied, R.drawable.challenge_failed,
R.drawable.classic_rage, R.drawable.one_does_not_simply,
R.drawable.computer_stare, R.drawable.computer_slice,
R.drawable.concentrated, R.drawable.concentrate,
R.drawable.concentrated_teeth, R.drawable.cry_pc,
R.drawable.dat_ass, R.drawable.desk_flip,
R.drawable.double_facepalm, R.drawable.duck_yeah,
R.drawable.fap, R.drawable.fap_accepted,
R.drawable.fap_gentleman, R.drawable.feels_good_man,
R.drawable.forever_a_gamer, R.drawable.forever_alone_clean,
R.drawable.forever_alone_sad, R.drawable.forever_alone_together,
R.drawable.fuck_that_bitch_yao_pff, R.drawable.fuck_that_yao_ming,
R.drawable.fuck_yeah, R.drawable.fuck_yeah_close_enough,
R.drawable.gentleman_troll, R.drawable.happy_smoking,
R.drawable.haters_gonna_hate, R.drawable.if_you_know_what_i_mean_mr_bean,
R.drawable.if_you_know_what_i_mean_mr_bean_blank, R.drawable.if_you_know_what_i_mean_mr_bean_blank,
R.drawable.impossibru, R.drawable.indeed,
R.drawable.jesus, R.drawable.keyboard_break,
R.drawable.knowthatfeel, R.drawable.like_a_sir,
R.drawable.long_long_neck_surprise, R.drawable.look_from_bottom,
R.drawable.me_gusta, R.drawable.me_gusta_creepy,
R.drawable.me_gusta_makeup, R.drawable.not_sure_if_gusta,
R.drawable.now_kiss, R.drawable.one_does_not_simply,
R.drawable.sample_1, R.drawable.sample_4,
R.drawable.sample_7, R.drawable.sample_12,
R.drawable.sample_13, R.drawable.today_is_monday,
R.drawable.trees_smile, R.drawable.trees_stoned,
R.drawable.trees_stoned_exhale, R.drawable.trees_stoned_inhale,
R.drawable.wonka, R.drawable.y_u_no,
R.drawable.yea_science, R.drawable.you_are_the_man
};
// Constructor
public ImageAdapter(Context c){
mContext = c;
}
#Override
public int getCount() {
return mThumbIds.length;
}
#Override
public Object getItem(int position) {
return mThumbIds[position];
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
.....
Then i tried 2 Solutions:
First:
public View getView(int position, View convertView, ViewGroup parent) {
//This actually is a bad solution, because every time convertView is reused, you will still initialize new ImageView, which is wrong
//ImageView imageView = new ImageView(this.mContext);
//new BitmapWorkerTask(imageView).execute(Tattoos[position]);
//return imageView;
//Better solution
ImageView imageView = null;
if (convertView == null) {
imageView = new ImageView(this.mContext);
new BitmapWorkerTask(imageView).execute(Tattoos[position]);
//create new ImageView if it is not present and populate it with some image
} else {
imageView = (ImageView) convertView;
//re-use ImageView that already exists in memory
}
return imageView;
}
class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
private int data = 0;
public BitmapWorkerTask(ImageView imageView) {
// Use a WeakReference to ensure the ImageView can be garbage collected
imageViewReference = new WeakReference<ImageView>(imageView);
}
// Decode image in background.
#Override
protected Bitmap doInBackground(Integer... params) {
data = params[0];
return decodeSampledBitmapFromResource(ImageAdapter.this.mContext.getResources(), data, 100, 100);
}
// Once complete, see if ImageView is still around and set bitmap.
#Override
protected void onPostExecute(Bitmap bitmap) {
if (imageViewReference != null && bitmap != null) {
final ImageView imageView = imageViewReference.get();
if (imageView != null) {
imageView.setImageBitmap(bitmap);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setLayoutParams(new GridView.LayoutParams(100, 70));
}
}
}
}
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
// Calculate ratios of height and width to requested height and width
final int heightRatio = Math.round((float) height / (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
// Choose the smallest ratio as inSampleSize value, this will guarantee
// a final image with both dimensions larger than or equal to the
// requested height and width.
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
}
But my problem is that the pictures are on each other so they lie on top of each other why???
2 Solution:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView = new ImageView(mContext);
// TextView txt = new TextView(mContext);
imageView.setImageResource(mThumbIds[position]);
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
imageView.setLayoutParams(
new GridView.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT));
Bitmap m_d = BitmapFactory.decodeResource(mContext.getResources(),
mThumbIds[position]);
if (m_d != null)
{
Bitmap resizedBitmap = Bitmap.createScaledBitmap(m_d, 205, 205, true);
imageView.setImageBitmap(resizedBitmap);
};
return imageView;}}
But that´s laggy as hell why???
thank you dudes for helping!!!

Whenever you create a Bitmap using BitmapFactory, you must be sure to call .recycle() on that bitmap instance when you're done with it, or else you'll very quickly run out of memory.
Your first solution is closer to correct because you need to recycle those convertView objects, so just make sure that your convertView exists, and that you've recycled any bitmaps that it might already be holding onto before you create new ones.
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView = null;
if (convertView == null) {
imageView = new ImageView(this.mContext);
} else {
imageView = (ImageView) convertView;
}
// clean up your old bitmap first, if there is one.
if(imageView.getDrawable() instanceof BitmapDrawable){
BitmapDrawable bd = (BitmapDrawable) imageView.getDrawable();
imageView.setDrawable(null);
if(bd.getBitmap() != null){
bd.getBitmap().recycle();
}
bd = null;
}
new BitmapWorkerTask(imageView).execute(Tattoos[position]);
return imageView;
}

Related

Image slider using viewPager. freeze while sliding

I'm created app, which gets images from gallery, shows in VewPager and we can slide it. There only problem is that if the image size is more than 1mb, the slide freezes, lagging. If i add images in gallery 100-200kb, that not freeze. Any solution? Thanks.
Here the adapter.
public class PhotoPagerAdapter extends PagerAdapter {
private ImageView imageView;
private Context context;
private LayoutInflater inflater;
private ArrayList<String> listOfAllImages = new ArrayList<>();
private ArrayList<Bitmap> listOfAllBitmap = new ArrayList<>();
public PhotoPagerAdapter(Context context) {
this.context = context;
getAllShownImagesPath();
}
#Override
public int getCount() {
return listOfAllImages.size();
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.photopager, null);
imageView = (ImageView) view.findViewById(R.id.photoView2);
imageView.setImageBitmap(listOfAllBitmap.get(position));
imageView.setRotation(90);
ViewPager viewPager = (ViewPager) container;
viewPager.addView(view, 0);
return view;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
ViewPager vp = (ViewPager) container;
View view = (View) object;
vp.removeView(view);
}
private void getAllShownImagesPath() {
Uri uri;
Cursor cursor;
int column_index_data;
String absolutePathOfImage;
uri = android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
String[] projection = {MediaStore.MediaColumns.DATA,
MediaStore.Images.Media.BUCKET_DISPLAY_NAME};
cursor = context.getContentResolver().query(uri, projection, null,
null, null);
column_index_data = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
while (cursor.moveToNext()) {
absolutePathOfImage = cursor.getString(column_index_data);
listOfAllImages.add(absolutePathOfImage);
listOfAllBitmap.add(BitmapFactory.decodeFile(absolutePathOfImage));
}
cursor.close();
}
}
And here's the fragment.
public class ShowCamera2 extends BaseFragment{
private View mainView;
private ViewPager viewPager;
private PhotoPagerAdapter photoPagerAdapter;
private Button prev, next;
private TextView imageCount;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mainView = inflater.inflate(R.layout.camera_fragment, container, false);
prev = (Button) mainView.findViewById(R.id.prevPhoto2);
next = (Button) mainView.findViewById(R.id.nextPhoto2);
viewPager = (ViewPager) mainView.findViewById(R.id.viewPager);
photoPagerAdapter = new PhotoPagerAdapter(this.getActivity());
viewPager.setAdapter(photoPagerAdapter);
prev.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
viewPager.setCurrentItem(viewPager.getCurrentItem() - 1);
}
});
next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
viewPager.setCurrentItem(viewPager.getCurrentItem() + 1);
}
});
return mainView;
}
}
Anyone can help me? Thank you for reading.
Here the update.
public class PhotoPagerAdapter extends PagerAdapter {
private ImageView imageView;
private Context context;
private LayoutInflater inflater;
private ArrayList<String> listOfAllImages = new ArrayList<>();
private ArrayList<Bitmap> listOfAllBitmap = new ArrayList<>();
public PhotoPagerAdapter(Context context) {
this.context = context;
getAllShownImagesPath();
}
#Override
public int getCount() {
return listOfAllBitmap.size();
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.photopager, null);
imageView = (ImageView) view.findViewById(R.id.photoView2);
imageView.setImageBitmap(listOfAllBitmap.get(position));
imageView.setRotation(90);
ViewPager viewPager = (ViewPager) container;
viewPager.addView(view, 0);
return view;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
ViewPager vp = (ViewPager) container;
View view = (View) object;
vp.removeView(view);
}
private void getAllShownImagesPath() {
Uri uri;
Cursor cursor;
int column_index_data;
String absolutePathOfImage;
uri = android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
String[] projection = {MediaStore.MediaColumns.DATA,
MediaStore.Images.Media.BUCKET_DISPLAY_NAME};
cursor = context.getContentResolver().query(uri, projection, null,
null, null);
column_index_data = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
while (cursor.moveToNext()) {
absolutePathOfImage = cursor.getString(column_index_data);
//listOfAllImages.add(absolutePathOfImage);
listOfAllBitmap.add(decodeBitmapURI(context, absolutePathOfImage, 1000, 500));
}
cursor.close();
}
public Bitmap decodeBitmapURI(Context context, String uri, int imageWidth, int imageHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
try {
BitmapFactory.decodeStream(context.getContentResolver().openInputStream(Uri.parse(uri)), null, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, imageWidth, imageHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeStream(context.getContentResolver().openInputStream(Uri.parse(uri)), null, options);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return null;
}
public int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) >= reqHeight
&& (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
}
Try this code
Picasso.with(mContext).
load(url) // from gallery load("file://" + url)
.centerCrop().placeholder(placeHolderRecource)
.resize(Utilities.dpToPx(100, mContext), Utilities.dpToPx(100, mContext)).into(imgView);
public static int dpToPx(int dp, Context mContext)
{
DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics();
int px = Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
return px;
}
Replace this linelistOfAllBitmap.add(BitmapFactory.decodeFile(absolutePathOfImage));
with
listOfAllBitmap.add(decodeBitmapURI(context, Uri.parse(new File(absolutePathOfImage).toString()), 700, 350););
Check below solution for Loading Large Images, as android docs:
public Bitmap decodeBitmapURI(Context context, Uri uri,int imageWidth, int imageHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
try {
BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri), null, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, imageWidth, imageHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri), null, options);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return null;
}
public int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) >= reqHeight
&& (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
I used Glide, and this helped me.
public class ImageAdapter extends PagerAdapter {
private ImageView imageView;
private Context context;
private LayoutInflater inflater;
private ArrayList<String> listOfAllImages = new ArrayList<>();
public ImageAdapter(Context context) {
this.context = context;
getAllShownImagesPath();
}
#Override
public int getCount() {
return listOfAllImages.size();
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.photopager, null);
imageView = (ImageView) view.findViewById(R.id.photoView2);
Glide.with(context).load(listOfAllImages.get(position))
.thumbnail(1f)
.crossFade()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(imageView);
ViewPager viewPager = (ViewPager) container;
viewPager.addView(view, 0);
return view;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
ViewPager vp = (ViewPager) container;
View view = (View) object;
vp.removeView(view);
}
private void getAllShownImagesPath() {
Uri uri;
Cursor cursor;
int column_index_data;
String absolutePathOfImage;
uri = android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
String[] projection = {MediaStore.MediaColumns.DATA,
MediaStore.Images.Media.BUCKET_DISPLAY_NAME};
cursor = context.getContentResolver().query(uri, projection, null,
null, null);
column_index_data = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
while (cursor.moveToNext()) {
absolutePathOfImage = cursor.getString(column_index_data);
listOfAllImages.add(absolutePathOfImage);
}
cursor.close();
}
}

How to swap images in a GridView (Android)

I'm working on a slider puzzle Android app, so I'm using a GridView to display 16 images representing tiles. One of the tiles will consist of a plain white image (representing the background). The idea is that if the user clicks on any tile neighboring the white tile, the selected tile and the white tile will switch positions.
I'm trying to implement this by setting the white tile to the tile selected by the user, and vice versa. I saved the position of the white tile (it starts off at position 15) in the variable masterTilePos, and using the ImageAdapter Integer array referring to the images in my R.drawable file, set the image at masterValPos to the image at the selected index, and the selected image to the white tile. However, when I run the program, the tiles only successfully switch the first time: after that, it doesn't work properly and the order of the tiles within the GridView is ruined. I think it may because the array is simply referring to the actual image objects, but I'm not sure how to what to do instead; it has already been three days since I ran into this problem. Here is my code:
//GRID VIEW
public class MainActivity extends ActionBarActivity {
int masterTilePos = 15;
GridView gridview;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gridview = (GridView) findViewById(R.id.gridview);
gridview.setAdapter(new ImageAdapter(this));
gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
//These methods check if a neighboring tile is white, if there is one, swap() is called
if(checkUp(position) || checkDown(position) || checkLeft(position) || checkRight(position)) {
swap(position);
}
}
});
}
public void swap(int pos) {
ImageAdapter updater = new ImageAdapter(this);
//This is where I try to switch the images, and seems to be the source of the problem
int val = updater.mThumbIds[masterTilePos];
updater.mThumbIds[masterTilePos] = updater.mThumbIds[pos];
updater.mThumbIds[pos] = val;
updater.notifyDataSetChanged();
gridview.setAdapter(updater);
gridview.invalidateViews();
masterTilePos = pos;
}
}
//IMAGE ADAPTER
public class ImageAdapter extends BaseAdapter {
private Context mContext;
public ImageAdapter(Context c) {
mContext = c;
}
public int getCount() {
return mThumbIds.length;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
// if it's not recycled, initialize some attributes
DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();
int width = metrics.widthPixels / 4;
int height = metrics.heightPixels / 4;
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(width, height));
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.setPadding(1, 1, 1, 1);
}
else {
imageView = (ImageView) convertView;
}
imageView.setImageResource(mThumbIds[position]);
return imageView;
}
// the array containing references to the images
public Integer[] mThumbIds = {
R.drawable.pic1,
R.drawable.pic2,
R.drawable.pic3,
R.drawable.pic4,
R.drawable.pic5,
R.drawable.pic6,
R.drawable.pic7,
R.drawable.pic8,
R.drawable.pic9,
R.drawable.pic10,
R.drawable.pic11,
R.drawable.pic12,
R.drawable.pic13,
R.drawable.pic14,
R.drawable.pic15,
R.drawable.background
};
}
Can anyone please help me solve this so I can successfully switch the images within the grid? Thanks.
In onCreate you are doing:
gridview.setAdapter(new ImageAdapter(this));
So, you created adapter, without assign it to any variable. This is wrong!
Then, every swap you create new Adapter:
ImageAdapter updater = new ImageAdapter(this);
And you are setting it as current adapter:
gridview.setAdapter(updater);
This is wrong as well.
You must do in such a way:
OnCreate -> create adapter, assign it to objects's variable (property)
Then you need to work only with that variable.
And then, if you have a problem, debug your logic in SWAP method.
//GRID VIEW
public class MainActivity extends ActionBarActivity {
int masterTilePos = 15;
GridView gridview;
ImageAdapter imageAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gridview = (GridView) findViewById(R.id.gridview);
imageAdapter= new ImageAdapter(this);
gridview.setAdapter(imageAdapter);
gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
//These methods check if a neighboring tile is white, if there is one, swap() is called
if(checkUp(position) || checkDown(position) || checkLeft(position) || checkRight(position)) {
swap(position);
}
}
});
}
public void swap(int pos) {
//This is where I try to switch the images, and seems to be the source of the problem
int val = imageAdaptor.mThumbIds[masterTilePos];
imageAdapter.mThumbIds[masterTilePos] = imageAdapter.mThumbIds[pos];
imageAdapter.mThumbIds[pos] = val;
imageAdapter.notifyDataSetChanged();
gridview.invalidateViews();
masterTilePos = pos;
}
}
//IMAGE ADAPTER
public class ImageAdapter extends BaseAdapter {
private Context mContext;
public ImageAdapter(Context c) {
mContext = c;
}
public int getCount() {
return mThumbIds.length;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
// if it's not recycled, initialize some attributes
DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();
int width = metrics.widthPixels / 4;
int height = metrics.heightPixels / 4;
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(width, height));
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.setPadding(1, 1, 1, 1);
}
else {
imageView = (ImageView) convertView;
}
imageView.setImageResource(mThumbIds[position]);
return imageView;
}
// the array containing references to the images
public Integer[] mThumbIds = {
R.drawable.pic1,
R.drawable.pic2,
R.drawable.pic3,
R.drawable.pic4,
R.drawable.pic5,
R.drawable.pic6,
R.drawable.pic7,
R.drawable.pic8,
R.drawable.pic9,
R.drawable.pic10,
R.drawable.pic11,
R.drawable.pic12,
R.drawable.pic13,
R.drawable.pic14,
R.drawable.pic15,
R.drawable.background
};
}

Blank image in Gallery view – Android

I know about gallery view is outdated, but i still need it.
I've tested it on Nexus 7, Samsung S4, LG phones and it works fine, but on HTC phone I got blank place instead some images in Gallery, like this:
Here is a sample of code:
<Gallery
android:layout_marginTop="5dp"
android:id="#+id/gallery1"
android:layout_width="match_parent"
android:layout_height="350dp" />
class ImageAdapter extends BaseAdapter {
#Override
public int getCount() {
return images.size();
}
#Override
public Object getItem(int arg0) {
return null;
}
#Override
public long getItemId(int arg0) {
return 0;
}
#Override
public View getView(int position, View view, ViewGroup vg) {
ImageView image = new ImageView(getApplicationContext());
image.setImageResource(images.get(position));
image.setPadding(20, 20, 20, 20);
image.setLayoutParams(new Gallery.LayoutParams(550, 450));
image.setScaleType(ImageView.ScaleType.FIT_XY);
return image;
}
}
what is wrong with it?
I have used the article and it works for me now.
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}

ImageView will not resize properly

I'm attempting to get an imageview (classical_up_btn) to fill the width of the screen correctly however it appears to be cut off by the next image it is supposed to load when swiped
Any suggestions as to how this can be resolved?
Thanks!
SCREENSHOT:
JAVA:
private class ImagePagerAdapter extends PagerAdapter {
private int[] mImages = new int[] { R.drawable.classical_up_btn,
R.drawable.country_up_btn, R.drawable.dance_up_btn,
R.drawable.hiphop_up_btn };
public int getCount() {
return mImages.length;
}
public boolean isViewFromObject(View view, Object object) {
return view == ((ImageView) object);
}
public Object instantiateItem(ViewGroup container, int position) {
Context context = Home.this;
ImageView imageView = new ImageView(context);
int padding = context.getResources().getDimensionPixelSize(
R.dimen.padding_medium);
imageView.setPadding(padding, padding, padding, padding);
imageView.setScaleType(ImageView.ScaleType.CENTER);
imageView.setImageResource(mImages[position]);
((ViewPager) container).addView(imageView, 0);
return imageView;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
((ViewPager) container).removeView((ImageView) object);
}
}
}
imageView.setScaleType(ImageView.ScaleType.CENTER);
should be:
imageView.setScaleType(ImageView.ScaleType.FIT_XY);

gridview showing the same image in repetition

Here is the code for the gridview, it shows the same images in a repetition, the sample images 2 and 3 are shown over and over again, what should i do?
public class GridViewImageAdapter extends BaseAdapter {
private Context mContext;
public GridViewImageAdapter(Context c) {
mContext = c;
}
public int getCount() {
return mThumbIds.length;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
//ImageView imageView;
ImageView icon;
if (convertView == null) { // if it's not recycled, initialize some attributes
icon = new ImageView(mContext);
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View row=inflater.inflate(R.layout.grid_icon, parent, false);
icon=(ImageView)row.findViewById(R.id.album_image);
icon.setScaleType(ImageView.ScaleType.CENTER_CROP);
icon.setImageResource(mThumbIds[position]);
//overlay
View overlay = (View) row.findViewById(R.id.overlay);
int opacity = 100; // from 0 to 255
overlay.setBackgroundColor(opacity * 0x1000000); // black with a variable alpha
FrameLayout.LayoutParams params =
new FrameLayout.LayoutParams(FrameLayout.LayoutParams.FILL_PARENT, 600);
params.gravity = Gravity.CENTER;
overlay.setLayoutParams(params);
overlay.invalidate();
return row;
}
return convertView;
}
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
}
// references to our images
private Integer[] mThumbIds = {
R.drawable.sample_2, R.drawable.sample_3,
R.drawable.sample_4, R.drawable.sample_5,
R.drawable.sample_6, R.drawable.sample_7,
R.drawable.sample_0, R.drawable.sample_1
};
}
It's becuase you are returning the same view repeatedly.
convertView is a reused view, so once it's been used and is no longer null, you are returning it without changing it.
Change to this
if (convertView == null) { // if it's not recycled, initialize some attributes
icon = new ImageView(mContext);
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.grid_icon, parent, false);
}
icon=(ImageView)row.findViewById(R.id.album_image);
icon.setScaleType(ImageView.ScaleType.CENTER_CROP);
icon.setImageResource(mThumbIds[position]);
//overlay
View overlay = (View) convertView.findViewById(R.id.overlay);
int opacity = 100; // from 0 to 255
overlay.setBackgroundColor(opacity * 0x1000000); // black with a variable alpha
FrameLayout.LayoutParams params =
new FrameLayout.LayoutParams(FrameLayout.LayoutParams.FILL_PARENT, 600);
params.gravity = Gravity.CENTER;
overlay.setLayoutParams(params);
overlay.invalidate();
return convertView;
The above should work, it's inefficient though, you should look up the ViewHolder pattern

Categories