I follow the example in this link :
Viewpager Example in android
its work fine but when i placed my own high resolution images (large in size ), it gave me exception :
java.lang.OutOfMemoryError: bitmap size exceeds VM budget.
i post an old question about that but it closed coz its duplicated for that reason , i tried and searched alot, finally i found the solution which is : scaling my images to avoid memory exception by following :
author advice and answers here in stackfllow and android development site , i ended with the bellow code , which also end with same exception, i think there is some wrong in my code coz im still learning java and android development , but that what i can end with , please any help or advice will be appreciated ,
thanks .
my code:
ViewPagerAdapter
public class ViewPagerAdapter extends PagerAdapter {
Activity activity;
int imageArray[];
public ViewPagerAdapter(Activity act, int[] imgArra) {
imageArray = imgArra;
activity = act;
}
public int getCount() {
return imageArray.length;
}
public Object instantiateItem(View collection, int position) {
ImageView view = new ImageView(activity);
view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
view.setScaleType(ScaleType.FIT_XY);
view.setBackgroundResource(imageArray[position]);
((ViewPager) collection).addView(view, 0);
return view;
}
#Override
public void destroyItem(View arg0, int arg1, Object arg2) {
((ViewPager) arg0).removeView((View) arg2);
}
#Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == ((View) arg1);
}
#Override
public Parcelable saveState() {
return null;
}
public static Bitmap decodeSampledBitmapFromResource(String imageArra,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(imageArra, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(imageArra, 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) {
if (width > height) {
inSampleSize = Math.round((float)height / (float)reqHeight);
} else {
inSampleSize = Math.round((float)width / (float)reqWidth);
}
}
return inSampleSize;}}
PageIndicatorActivity:
public class PageIndicatorActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewPagerAdapter adapter = new ViewPagerAdapter(this, imageArra);
ViewPager myPager = (ViewPager) findViewById(R.id.myfivepanelpager);
myPager.setAdapter(adapter);
myPager.setCurrentItem(0);
}
private int imageArra[] = { R.drawable.one, R.drawable.two,
R.drawable.three, R.drawable.four,
R.drawable.five, R.drawable.six,
R.drawable.seven, R.drawable.eight,R.drawable.nine,
R.drawable.ten }; }
logcat stack :
FATAL EXCEPTION: main
java.lang.OutOfMemoryError: bitmap size exceeds VM budget
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:563)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:439)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697)
at android.content.res.Resources.loadDrawable(Resources.java:1709)
at android.content.res.Resources.getDrawable(Resources.java:581)
at android.view.View.setBackgroundResource(View.java:7586)
at com.horizontalscrollviewwithpageindicator.ViewPagerAdapter.instantiateItem
(ViewPagerAdapter.java:33)
at android.support.v4.view.PagerAdapter.instantiateItem(PagerAdapter.java:110)
at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:692)
at android.support.v4.view.ViewPager.populate(ViewPager.java:875)
at android.support.v4.view.ViewPager.populate(ViewPager.java:772)
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1234)
at android.view.View.measure(View.java:8366)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1017)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:386)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:309)
at android.view.View.measure(View.java:8366)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:250)
at android.view.View.measure(View.java:8366)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:250)
at android.view.View.measure(View.java:8366)
at android.view.ViewRoot.performTraversals(ViewRoot.java:844)
at android.view.ViewRoot.handleMessage(ViewRoot.java:1865)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:3687)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
at dalvik.system.NativeStart.main(Native Method)
Try the following tips.
- Android works well with .png images, where the same size image in .jpg format creates a OutOfMemoryError.
See this link for the solution from official Android Developers Site:
http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
You never use the method to scale the images, also your inSampleSize needs to be a power of two(i believe). These images are way too big (4.5 mb that you stated in your previous post). On top of a huge bitmap being stored, the view pager keeps 3 views in memory at any given time. Your memory allocated for your view pager is something like >13.5mb. Replace your instantiate view with the following:
ImageView myView = new ImageView(context);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
Bitmap bitmap = BitmapFactory.decodeResource(activity.getResouces(), imageArray[position], options );
myView.setImageBitmap(bitmap);
((ViewPager) view).addView(myView);
return myView;
If this still provides an error, use options.inSampleSize = 8;
Related
I am having crashes in a gridview using NOSTRAs UniversalImageLoader. There are around 1.5k images in the list to scroll through. But i guess its not related the bitmaps themself in the memory, but its related to too many thread creations. Basically i am scrolling up and down and up and down very wild. And i guess there are too many thread created and i am seeing this in the log very often
D/dalvikvm: create interp thread : stack size=32KB
D/dalvikvm: create new thread
D/dalvikvm: new thread created
D/dalvikvm: update thread list
and eventually i see
E/dalvikvm: Thread creation failed (err=Invalid argument, stacksize=1085584KB)
A/libc: Fatal signal 7 (SIGBUS) at 0x84849142 (code=1), thread 28383 (nomad5.beatsnap)
or sometimes this
E/dalvikvm: Thread creation failed (err=Invalid argument, stacksize=1085584KB)
A/libc: Fatal signal 11 (SIGSEGV) at 0x84849142 (code=2), thread 14546 (nomad5.beatsnap)
sometimes is paired with
java.lang.OutOfMemoryError: pthread_create (stack size 16384 bytes) failed: Try again
but sometimes this crash is not shown in the log. Here is my UIL config
.denyCacheImageMultipleSizesInMemory().diskCacheSize(64 * 1024 * 1024).threadPoolSize(5);
and here my display options
.bitmapConfig(Bitmap.Config.RGB_565)
.imageScaleType(ImageScaleType.IN_SAMPLE_INT)
.cacheInMemory(false).cacheOnDisk(true).showImageOnFail(R.drawable.ic_image_choose_error)
.showImageForEmptyUri(R.drawable.ic_image_choose_error)
I am loading images already in a very small size. Here is the loading call
ImageLoader.getInstance()
.displayImage("file://" + this.imageList.get(position),
new ImageViewAware(imageView),
this.options,
new ImageSize(100, 100),
new SimpleImageLoadingListener()
{
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage)
{
...
}
},
null);
By the way, my apps memory is constantly stable at around 40MB.
So as you see i disabled all the memory caching. I am also using large heap in the XML.
Any suggestions how to avoid this crashes? Is there a way to limit the thread creation counts?
Update #1
I have tried it with loadImage and removed all other code. Its still happening.
Here is my adapter code. The imageList is a list with ~1.5k entries. Just paths to the images on the phone.
public class ImageAdapter extends BaseAdapter
{
// all the paths
private final ArrayList<String> imageList;
// the layout inflater
private final LayoutInflater layoutInflater;
// checked array
private final SparseBooleanArray checkedArray = new SparseBooleanArray();
// options for loading into the grid
private final DisplayImageOptions options;
/**
* Constructor to use
*/
public ImageAdapter(#NonNull Context context,
#NonNull ArrayList<String> imageList)
{
// init members
this.layoutInflater = LayoutInflater.from(context);
this.imageList = imageList;
// image options
this.options = new DisplayImageOptions.Builder().bitmapConfig(Bitmap.Config.RGB_565)
.imageScaleType(ImageScaleType.IN_SAMPLE_INT)
.cacheInMemory(false)
.cacheOnDisk(true)
.showImageOnFail(R.drawable.ic_image_choose_error)
.showImageForEmptyUri(R.drawable.ic_image_choose_error)
.imageScaleType(ImageScaleType.EXACTLY)
.build();
}
#Override
public int getCount()
{
return this.imageList.size();
}
#Override
public Object getItem(int position)
{
return null;
}
#Override
public long getItemId(int position)
{
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
if(convertView == null)
{
convertView = this.layoutInflater.inflate(R.layout.fragment_image_choose_element, null);
}
convertView.setTag(position);
// load the image
final View finalConvertView = convertView;
ImageLoader.getInstance()
.loadImage("file://" + this.imageList.get(position),
new ImageSize(100, 100),
this.options,
null);
return convertView;
}
}
and here is the file fragment_image_choose_element.xml that is inflated in the getView method:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id = "#+id/image_choose_element"
xmlns:android = "http://schemas.android.com/apk/res/android"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:layout_gravity = "center"
android:gravity = "center">
<ImageView
android:id = "#+id/image_choose_element_image"
android:layout_width = "match_parent"
android:layout_height = "match_parent"
android:adjustViewBounds = "false"
android:scaleType = "centerCrop"/>
</RelativeLayout>
What i've tried to far:
Calling measure()
tv.measure(0, 0);
int height = tv.getMeasuredHeight();
Calling measure() with specified sizes/modes
int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(99999, View.MeasureSpec.AT_MOST);
int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
tv.measure(widthMeasureSpec, heightMeasureSpec);
int height = tv.getMeasuredHeight();
Calling getTextBounds()
Rect bounds = new Rect();
tv.getPaint().getTextBounds(tv.getText().toString(), 0, tv.getText().length(), bounds);
int height = bounds.height();
Calling measure() and then calling getTextBounds()
Calling getLineCount() * getLineHeight()
None seem to work. They all return incorrect values (container view gets incorrect height - it's either too small or too large)
Ideas on how to calculate this simple thing??
You need to specify the available width so the height can be properly calculated.
Note: In cases where you just need to get the height of a view that is already drawn, use ViewTreeObserver. See this question for a thing to consider in that case.
This is why I do, in a piece of code where I want to scale a view from hidden to its full necessary height:
int availableWidth = getParentWidth(viewToScale);
int widthSpec = View.MeasureSpec.makeMeasureSpec(availableWidth, View.MeasureSpec.AT_MOST);
int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
viewToScale.measure(widthSpec, heightSpec);
int measuredHeight = viewToScale.getMeasuredHeight();
// Offtopic: Now I animate the height from 1 to measuredHeight (0 doesn't work)
You may pass the availableWidth yourself, but I calculate it from the parent:
private int getParentWidth(View viewToScale)
{
final ViewParent parent = viewToScale.getParent();
if (parent instanceof View) {
final int parentWidth = ((View) parent).getWidth();
if (parentWidth > 0) {
return parentWidth;
}
}
throw new IllegalStateException("View to scale must have parent with measured width");
}
Where are you calling those methods?
The best way to do what you are trying to do is to use ViewTreeObserver and add onPreDrawListener.
Take a look at this i think it will help
What you can do here is get ViewTreeObserver associated with this TextView and add OnGlobalLayoutListener to it:
final ViewTreeObserver vto = textView.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
// textView dimensions are calculated at this stage, but textView
// isn't rendered yet. Do what you need to do and remove OnGlobalLayoutListener
// after
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
textView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
textView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
}
}
I had a similar problem recently, trying to measure the height of a ViewGroup containing several multiline TextView.
What worked for me was to measure() the TextView, then add (lineCount-1)*lineHeight to its measuredHeight.
Here is the code to measure only one TextView :
private int getMeasuredHeight(TextView textView) {
textView.measure(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
int height = textView.getMeasuredHeight();
height += (textView.getLineCount()-1) * textView.getLineHeight();
return height;
}
And in the case of a ViewGroup with many TextViews, here is my code :
private int getMeasuredHeight(ViewGroup viewGroup) {
viewGroup.measure(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
int height = viewGroup.getMeasuredHeight();
for(TextView textView : findAllTextView(viewGroup)) {
height += (textView.getLineCount()-1) * textView.getLineHeight();
}
return height;
}
private List<TextView> findAllTextView(ViewGroup v) {
List<TextView> result = new ArrayList<>();
for (int i = 0; i < v.getChildCount(); i++) {
Object child = v.getChildAt(i);
if (child instanceof TextView)
result.add((TextView) child);
else if (child instanceof ViewGroup)
for(TextView tv: findAllTextView((ViewGroup) child))
result.add(tv);
}
return result;
}
I have a ArrayList with two columns and I display a image with text below. I am using high quality images and need to display those images in the grid view with a decent quality for which I am using BitmapFactory.Options. I am using the same code from google but that still throws me an OutOfMemory error.
CODE :
BitmapFactory.Options obj = new BitmapFactory.Options();
obj.inPurgeable = true;
obj.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.drawable.car, obj);
BitmapFactory.decodeResource(getResources(), R.drawable.nature, obj);
obj.inSampleSize = 4;
obj.inJustDecodeBounds = false;
Bitmap homeIcon = BitmapFactory.decodeResource(getResources(), R.drawable.car,obj);
Bitmap userIcon = BitmapFactory.decodeResource(getResources(), R.drawable.nature,obj);
gridArray.add(new Item(homeIcon,"Home"));
gridArray.add(new Item(userIcon,"User"));
gridArray.add(new Item(homeIcon,"House"));
gridArray.add(new Item(userIcon,"Friend"));
gridArray.add(new Item(homeIcon,"Home"));
gridArray.add(new Item(userIcon,"Personal"));
gridArray.add(new Item(homeIcon,"Home"));
gridArray.add(new Item(userIcon,"User"));
gridArray.add(new Item(homeIcon,"Building"));
gridArray.add(new Item(userIcon,"User"));
gridArray.add(new Item(homeIcon,"Home"));
gridArray.add(new Item(userIcon,"xyz"));
UPDATE :
Item.java :
public class Item {
Bitmap image;
String title;
public Item(Bitmap image, String title) {
super();
this.image = image;
this.title = title;
}
public Bitmap getImage() {
return image;
}
public void setImage(Bitmap image) {
this.image = image;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
This is the code and I have another class name Item which has a constructor with arguments as Bitmap and String. While executing this, it throws me an OutOfMemoryError. I am not sure whether I should add any other extras in these code. Any help will be appreciated guys.
This Error occurs usually when loading large bitmaps. Are the drawables for you ImageButtons high resolution? If so, this is likely the error. You try downsampling them to their appropriate resolution, but for a quick-fix, adding android:largeHeap="true" under the <application> tag of your AndroidManifest.xml file can sometimes allow your application to load large images without an out of memory error.
The reason you use the same code from Google yet still receive the out of memory error is not just the high resolution of the bitmaps, but also the large amount you are loading at once.
Adding a small wait between them can spread the load and make a cute little animation depending on you layout, just an idea (But of course don't do it on the UI Thread).
Good Luck!
You can try to use android:largeHeap="true" inside the application tag on AndroidManifest to avoid some out of memory erros on your app. It will let your app to use more ram.
try removing first two decode statements made in fly which are causing the problem as your bitmaps are loaded there without sampling
you can modify below code according to your need.I hope it will help you.
Bitmap imageProcess(String path) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
imageBitmap = BitmapFactory.decodeFile(path, options);
options.inSampleSize = calculateInSampleSize(options,
displayMetrics.widthPixels,
(int) (displayMetrics.heightPixels * .75));
options.inJustDecodeBounds = false;
imageBitmap = BitmapFactory.decodeFile(path, options);
return imageBitmap;
}
public int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int heightRatio = Math.round((float) height
/ (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
inSampleSize = heightRatio > widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
I am trying to make a simple image gallery through which I can set wallpaper; I am using the below code to fetch the files from download folder and display it in scroll view.
I am able to do that, but now I want to fetch the currently displayed image so that I can set that image as wallpaper.
Below is the code I have for my activity class:
public class MainActivity extends Activity {
LinearLayout myGallery;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myGallery = (LinearLayout)findViewById(R.id.mygallery);
String ExternalStorageDirectoryPath = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
.getAbsolutePath();
String targetPath = ExternalStorageDirectoryPath ;
Toast.makeText(getApplicationContext(), targetPath, Toast.LENGTH_LONG).show();
File targetDirector = new File(targetPath);
File[] files = targetDirector.listFiles();
for (File file : files){
myGallery.addView(insertPhoto(file.getAbsolutePath()));
}
}
View insertPhoto(String path){
Bitmap bm = decodeSampledBitmapFromUri(path, 520, 520);
LinearLayout layout = new LinearLayout(getApplicationContext());
layout.setLayoutParams(new LayoutParams(550, 550));//Size of view
layout.setGravity(Gravity.CENTER);
ImageView imageView = new ImageView(getApplicationContext());
imageView.setLayoutParams(new LayoutParams(520, 520));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setImageBitmap(bm);
layout.addView(imageView);
return layout;
}
public Bitmap decodeSampledBitmapFromUri(String path, int reqWidth, int reqHeight) {
Bitmap bm = null;
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
bm = BitmapFactory.decodeFile(path, options);
return bm;
}
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) {
if (width > height) {
inSampleSize = Math.round((float)height / (float)reqHeight);
} else {
inSampleSize = Math.round((float)width / (float)reqWidth);
}
}
return inSampleSize;
}
}
Please tell me how I can fetch the image which is currently displayed in the scroll view.
Thanks
Aman
its been 5 months yet not answered, but i think i will try to answer it.
I think you need a custom view ie. with canvas. create a canvas and then create a bitmap in canvas. After that when you get a bitmap from linear layout in the form of URI, in your code a method decodeSampledBitmapFromUri you are getting a bitmap, simply assign the bitmap to the created bitmap on the canvas.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
java.lang.OutOfMemoryError: bitmap size exceeds VM budget - Android
I used ViewPager to show set of images from resource folder , if my images was small in size every thing works fine ,
but when i replace it with high definition images which i need it to be in my app , it gave me this error :
java.lang.OutOfMemoryError: bitmap size exceeds VM budget
note 1 :
i have now 5 images in my code for testing but finally i will have around 30 high definition images ,
note 2 :
i wonder why this happen , i am new to android and first time to use viewpager class , before i used gallery class in another app with more than 30 high definition images and no exception happend .
any advice will be appreciated , thanks alot
my code :
logcat stack:
FATAL EXCEPTION: main
java.lang.OutOfMemoryError: bitmap size exceeds VM budget
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:563)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:439)
at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:462)
at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:488)
at com.test.demo.MyPagerAdapter.<init>(MyPagerAdapter.java:42)
at com.test.demo.MainActivity.onCreate(MainActivity.java:15)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1615)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1667)
at android.app.ActivityThread.access$1500(ActivityThread.java:117)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:3687)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
at dalvik.system.NativeStart.main(Native Method)
MainActivity
public class MainActivity extends Activity {
private ViewPager mMyPager;
private MyPagerAdapter mMyPagerAdapter;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mMyPager = (ViewPager) findViewById(R.id.mypages);
mMyPagerAdapter = new MyPagerAdapter(this);
mMyPager.setAdapter(mMyPagerAdapter); }}
MyPagerAdapter
public class MyPagerAdapter extends PagerAdapter {
private ArrayList<ImageView> mViewsList;
private Context mContext = null;
public MyPagerAdapter(Context context) {
mContext = context;
mViewsList = new ArrayList<ImageView>();
Resources resource = mContext.getResources();
Bitmap bMap1 = BitmapFactory.decodeResource(resource,
R.drawable.one);
ImageView image1 = new ImageView(mContext);
image1.setImageBitmap(bMap1);
mViewsList.add(image1);
Bitmap bMap2 = BitmapFactory.decodeResource(resource,
R.drawable.two );
ImageView image2 = new ImageView(mContext);
image2.setImageBitmap(bMap2);
mViewsList.add(image2);
Bitmap bMap3 = BitmapFactory.decodeResource(resource,
R.drawable.three);
ImageView image3 = new ImageView(mContext);
image3.setImageBitmap(bMap3);
mViewsList.add(image3);
Bitmap bMap4 = BitmapFactory.decodeResource(resource,
R.drawable.four);
ImageView image4 = new ImageView(mContext);
image4.setImageBitmap(bMap4);
mViewsList.add(image4);
Bitmap bMap5 = BitmapFactory.decodeResource(resource,
R.drawable.five);
ImageView image5 = new ImageView(mContext);
image5.setImageBitmap(bMap5);
mViewsList.add(image5);
}
#Override
public int getCount() {
return mViewsList.size();
}
#Override
public Object instantiateItem(View view, int position) {
View myView = mViewsList.get(position);
((ViewPager) view).addView(myView);
return myView;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
#Override
public void destroyItem(View view, int arg1, Object object) {
((ViewPager) view).removeView((ImageView) object);
}
}
Your Adaptor should not be written the way you have it. You should only be decoding the bitmaps in the instantiateItem method.
private Context context;
private ArrayList<Integer> mResourceList;
private Resources resource;
public MyPagerAdapter(Context context) {
this.context = context;
resource = context.getResources();
mResourceList = new ArrayList<Integer>();
mResourceList.add(R.drawable.one);
mResourceList.add(R.drawable.two);
mResourceList.add(R.drawable.three);
mResourceList.add(R.drawable.four);
mResourceList.add(R.drawable.five);
}
#Override
public Object instantiateItem(View view, int position) {
ImageView myView = new ImageView(context);
Bitmap bitmap = BitmapFactory.decodeResource(resource, mResourceList.get(position) );
myView.setImageBitmap(bitmap);
((ViewPager) view).addView(myView);
return myView;
}
Now, you need to make sure that your bitmaps are not exceeding the max size value (2048px x 2048px).
If you are, you must scale your image down. This can be done by adding a BitmapFactory.Options object to your BitmapFactory.decodeResouce parameters and setting the inSampleSize by a power of 2. Setting it by 2 will sample it down to 50%, 4 to 25%, etc.
BitmapFactory.Options options = new BitmapFactory.Options()
options.inSampleSize = 2
Bitmap bitmap = BitmapFactory.decodeResource(resource, mResouceList.get(position), options );
Hope this helped!
Size of your bitmap is very large,So try to scale your bitmap before loading it.
Syntax for scaling bitmap
Bitmap bitmapName= Bitmap.createScaledBitmap(sourceBitmap, width, height,
true);
Where width and height are the size you want for the image to be.
Your issue is that you're creating a bunch of bitmaps before really needing to.
Inside your instantiateView method, create the ImageView's and load the bitmaps and set them there. If you need, use your ArrayList to hold your resource ints to know which images to load if you need. This way, garbage collection will remove bitmaps as needed, and shouldn't cause memory issues.