first i would like to say that english is not my native language. So please forgive me my mistakes.
To my problem: I have a ViewPager
with 10 pages and tabs. The first window is for setting and the others are questions.
You start with the first question and i show an image, if you click "yes" "no" then you go to the next page where the second picture is shown with another question.
I get everytime the oom error (as i get to the 7 page). I read some tipps about it i now i use bitmap decoder everytime i bind the image to my ImageView
. But that dont help much. I still have the same problem. My decoder has *.inPurgeable = true;
I know there is an option to change your manifest.xml to allow more heap size but i think that will only delay the error. Can someone look through my code please and tell me something that i am doing wrong. Cause it seems to me fine but cause i am new to programming i could have made some big mistakes :)
My viewpager with the adapter:
public class WaldViewPager extends FragmentActivity implements ActionBar.TabListener {
private static AppSectionsPagerAdapter mAppSectionsPagerAdapter;
static private ViewPager mViewPager;
private static Context context;
public static int bitmap;
private int width, height;
private ViewGroup rootWald;
private static int textSize = 0;
private Dialog dialog;
public static int lastUsed = 1;
private static int ergebnis = 0;
private static int[] fragenListe = new int[8];
private static int[] antworten = new int[9];
public static void setErgebnis(int zahl){
ergebnis = zahl;
}
public static int getErgebnis(){
return ergebnis;
}
public static void setAntwort(int position, int antwort){
antworten[position-1] = antwort;
}
public static int getAntwort(int position){
return antworten[position-1];
}
public static void setPage(int position){
mViewPager.setCurrentItem(position, true);
}
public static int getPage(){
return mViewPager.getCurrentItem();
}
private void resetListe(){
for(int i=0; i<fragenListe.length; i++){
fragenListe[i]=0;
}
}
private void resetAntworten(){
for(int i=0; i<antworten.length; i++){
antworten[i]=0;
}
}
public static boolean getFrage(int position){
if(fragenListe[position-2] == 1){
return true;
}else{
return false;
}
}
public static void setPageVisible(int position, boolean status){
if(status == true){
fragenListe[position-2] = 1;
}else if(status == false){
fragenListe[position-2] = 0;
}
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_viewpager);
overridePendingTransition(R.anim.fade_out, R.anim.fade_in);
mAppSectionsPagerAdapter = new AppSectionsPagerAdapter(getSupportFragmentManager());
WaldViewPager.context = getApplicationContext();
berechneSchriftgroese();
setupHelpInfoDialog();
resetListe();
resetAntworten();
rootWald = (ViewGroup) findViewById(R.id.toast_layout_root);
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionBar.setLogo(R.drawable.fake);
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mAppSectionsPagerAdapter);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position){
actionBar.getTabAt(position).select();
ViewParent root = findViewById(android.R.id.content).getParent();
findAndUpdateSpinner(root, position);
}
private boolean findAndUpdateSpinner(Object root, int position){
if (root instanceof android.widget.Spinner){
Spinner spinner = (Spinner) root;
spinner.setSelection(position);
return true;
}else if (root instanceof ViewGroup){
ViewGroup group = (ViewGroup) root;
if (group.getId() != android.R.id.content){
for (int i = 0; i < group.getChildCount(); i++){
if (findAndUpdateSpinner(group.getChildAt(i), position)){
return true;
}
}
}
}
return false;
}
});
for (int i = 0; i < mAppSectionsPagerAdapter.getCount(); i++) {
actionBar.addTab(actionBar.newTab().setText(mAppSectionsPagerAdapter.getPageTitle(i)).setTabListener(this));
}
mViewPager.setCurrentItem(1, true);
}
@Override
public void onBackPressed() {
if (mViewPager.getCurrentItem() == 1) {
super.onBackPressed();
} else {
mViewPager.setCurrentItem(1, true);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.bottom_bar_frage, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_settings_frage:
if(mViewPager.getCurrentItem()==0){
mViewPager.setCurrentItem(lastUsed, true);
}else{
lastUsed = mViewPager.getCurrentItem();
mViewPager.setCurrentItem(0, true);
}
return true;
case R.id.menu_info:
dialog.show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void setupHelpInfoDialog(){
dialog = new Dialog(WaldViewPager.this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setCancelable(true);
dialog.setContentView(R.layout.dialog_info);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
TextView text = (TextView) dialog.findViewById(R.id.dialog_ueberschrift);
text.setText("Bedienung der App");
if(MainViewPager.getTextSize()!=0){
text.setTextSize(text.getTextSize()-MainViewPager.getTextSize());
}
text = (TextView) dialog.findViewById(R.id.dialog_text1);
text.setText("-Wischfunktion:");
if(MainViewPager.getTextSize()!=0){
text.setTextSize(text.getTextSize()-MainViewPager.getTextSize());
}
text = (TextView) dialog.findViewById(R.id.dialog_text1_sub);
text.setText("Zum Navigieren können Sie entweder auf die Tabs zurückgreifen oder Sie wischen das Fenster links oder rechts");
if(MainViewPager.getTextSize()!=0){
text.setTextSize(text.getTextSize()-MainViewPager.getTextSize());
}
text = (TextView) dialog.findViewById(R.id.dialog_text2);
text.setText("-Zoomfunktion:");
if(MainViewPager.getTextSize()!=0){
text.setTextSize(text.getTextSize()-MainViewPager.getTextSize());
}
text = (TextView) dialog.findViewById(R.id.dialog_text2_sub);
text.setText("Wenn Sie auf das Bild klicken, können Sie es mit 2 Fingern vergrößern bzw. verkleinern");
if(MainViewPager.getTextSize()!=0){
text.setTextSize(text.getTextSize()-MainViewPager.getTextSize());
}
text = (TextView) dialog.findViewById(R.id.dialog_text3);
text.setText("-Erklärungshilfe:");
if(MainViewPager.getTextSize()!=0){
text.setTextSize(text.getTextSize()-MainViewPager.getTextSize());
}
text = (TextView) dialog.findViewById(R.id.dialog_text3_sub);
text.setMovementMethod(LinkMovementMethod.getInstance());
text.setText(ClickableText.addClickablePart("Damit Sie wenig Zeit beim Suchen der Fremd/Fachwörtern verlieren, können Sie Wörter wie \u200EClypeus\u200E direkt hier nachschlagen", context, rootWald), BufferType.SPANNABLE);
if(MainViewPager.getTextSize()!=0){
text.setTextSize(text.getTextSize()-MainViewPager.getTextSize());
}
ImageView bild = (ImageView) dialog.findViewById(R.id.dialog_bild1);
ImageView bild = (ImageView) dialog.findViewById(R.id.dialog_bild1);
bild.setImageBitmap(DecodeImage.decode(bild.getContext().getResources(), R.drawable.swipe));
bild = (ImageView) dialog.findViewById(R.id.dialog_bild2);
bild.setImageBitmap(DecodeImage.decode(bild.getContext().getResources(),
R.drawable.swipe_bild));
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
mViewPager.setCurrentItem(tab.getPosition(), true);
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
AppSectionsPagerAdapter
public static class AppSectionsPagerAdapter extends FragmentStatePagerAdapter {
public AppSectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Parcelable saveState() {
return null;
}
@Override
public Fragment getItem(int i) {
switch (i) {
case 0:
return new SettingsFrage();
case 1:
return new FrageA();
case 2:
return new FrageB();
case 3:
return new FrageC();
case 4:
return new FrageD();
case 5:
return new FrageE();
case 6:
return new FrageF();
case 7:
return new FrageG();
case 8:
return new FrageH();
case 9:
return new FrageI();
}
return null;
}
@Override
public int getCount() {
return 10;
}
@Override
public float getPageWidth(int position) {
if(position == 0){
return super.getPageWidth(position)*0.6f;
}
return super.getPageWidth(position);
}
@Override
public CharSequence getPageTitle(int position) {
switch(position){
case 0:
return "Settings";
case 1:
return "Einkerbung";
case 2:
return "Einbuchtung";
case 3:
return "Farbe";
case 4:
return "Stirndreieck";
case 5:
return "Haare";
case 6:
return "Beborstung";
case 7:
return "Hinterhaupt";
case 8:
return "Pigmentierung";
case 9:
return "Mesosoma";
}
return null;
}
}
public static Context getContext(){
return WaldViewPager.context;
}
public static int getTextSize(){
return textSize;
}
private void berechneSchriftgroese(){
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
width = size.x;
height = size.y;
if(width<=480 || height<=480){
textSize = 12;
}
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
overridePendingTransition(R.anim.fade_out, R.anim.fade_in);
}
}
One of my question:
public class FrageB extends Fragment implements OnClickListener{
public static ImageView bild;
public static TextView ueberschrift, frage, frageZusatz1, frageZusatz2;
public static View viewA, viewB, viewC;
public static RadioButton auswahlA, auswahlB, auswahlC;
String stringUeberschrift = "Einbuchtung";
String stringFrage = "Welche Form hat der Hinterrand des Kopfes?";
String stringAuswahlA = "keine Delle";
String stringAuswahlB = "Delle";
String stringAuswahlC = "unsicher";
String stringFrageZusatz1 = "keine Delle: nicht oder nur schwach eingebuchtet, keine deutliche Delle";
String stringFrageZusatz2 = "Delle: tief eingebuchtet, deutliche Delle";
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fake_frage, container, false);
ViewGroup root = (ViewGroup) v.findViewById(R.id.toast_layout_root);
bild = (ImageView) v.findViewById(R.id.frage_bild);
frage = (TextView) v.findViewById(R.id.frage_frage);
ueberschrift = (TextView) v.findViewById(R.id.frage_ueberschrift);
auswahlA = (RadioButton) v.findViewById(R.id.frage_auswahl1);
auswahlB = (RadioButton) v.findViewById(R.id.frage_auswahl2);
auswahlC = (RadioButton) v.findViewById(R.id.frage_auswahl3);
frageZusatz1 = (TextView) v.findViewById(R.id.frage_zusatz1);
frageZusatz2 = (TextView) v.findViewById(R.id.frage_zusatz2);
viewA = (View) v.findViewById(R.id.fake_view1);
viewB = (View) v.findViewById(R.id.fake_view2);
viewC = (View) v.findViewById(R.id.fake_view3);
auswahlC.setEnabled(false);
bild.setOnClickListener(this);
auswahlA.setOnClickListener(this);
auswahlB.setOnClickListener(this);
auswahlC.setOnClickListener(this);
auswahlA.setEnabled(false);
auswahlB.setEnabled(false);
bild.setClickable(false);
if(WaldViewPager.getFrage(2)){
ZeigeFrage.unhide(2);
}
ueberschrift.setMovementMethod(LinkMovementMethod.getInstance());
frage.setMovementMethod(LinkMovementMethod.getInstance());
frageZusatz1.setMovementMethod(LinkMovementMethod.getInstance());
frageZusatz2.setMovementMethod(LinkMovementMethod.getInstance());
frageZusatz1.setText(ClickableText.addClickablePart(stringFrageZusatz1, WaldViewPager.getContext(), root), BufferType.SPANNABLE);
frageZusatz2.setText(ClickableText.addClickablePart(stringFrageZusatz2, WaldViewPager.getContext(), root), BufferType.SPANNABLE);
auswahlA.setText(stringAuswahlA);
auswahlB.setText(stringAuswahlB);
auswahlC.setText(stringAuswahlC);
ueberschrift.setText(ClickableText.addClickablePart(stringUeberschrift, WaldViewPager.getContext(), root), BufferType.SPANNABLE);
frage.setText(ClickableText.addClickablePart(stringFrage, WaldViewPager.getContext(), root), BufferType.SPANNABLE);
if(WaldViewPager.getTextSize()!=0){
auswahlA.setTextSize(auswahlA.getTextSize()-WaldViewPager.getTextSize());
auswahlB.setTextSize(auswahlB.getTextSize()-WaldViewPager.getTextSize());
auswahlC.setTextSize(auswahlC.getTextSize()-WaldViewPager.getTextSize());
ueberschrift.setTextSize(ueberschrift.getTextSize()-WaldViewPager.getTextSize());
frage.setTextSize(frage.getTextSize()-WaldViewPager.getTextSize());
frageZusatz1.setTextSize(frageZusatz1.getTextSize()-WaldViewPager.getTextSize());
frageZusatz2.setTextSize(frageZusatz2.getTextSize()-WaldViewPager.getTextSize());
}
return v;
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
if(WaldViewPager.getFrage(2)){
ZeigeFrage.unhide(2);
}
}
}
@Override
public void onClick(View v) {
if(v == bild){
Intent intent = new Intent(WaldViewPager.getContext(), ShowImage.class);
WaldViewPager.bitmap = R.drawable.frage2;
startActivity(intent);
}
if(v == auswahlA){
WaldViewPager.setAntwort(WaldViewPager.getPage(), 1);
WaldViewPager.setPageVisible(3, true);
WaldViewPager.setErgebnis(0);
WaldViewPager.setPage(3);
}
if(v == auswahlB){
//coptoformica
WaldViewPager.setAntwort(WaldViewPager.getPage(), 2);
WaldViewPager.setErgebnis(2);
Intent intent = new Intent(WaldViewPager.getContext(), ErgebnisB.class);
startActivity(intent);
}
if(v == auswahlC){
}
}
}
My decodeImage
public class DecodeImage {
public static Bitmap decode(Resources res, int resId){
BitmapFactory.Options bfOptions=new BitmapFactory.Options();
bfOptions.inDither = false;
bfOptions.inPurgeable = true;
bfOptions.inInputShareable = true;
bfOptions.inTempStorage = new byte[32 * 1024];
return BitmapFactory.decodeResource(res, resId, bfOptions);
}
}
I would appreciate any help. feel free to ask for over peaces of code. this app works fine on some devices but on other not. has to be something with heap size change i guess.
EDIT: found the solution.
the answer with the bitmap.recycle()
works but due to my art of code i was lazy to change a lot and i used something else.
as for ViewPager
android provides you with
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
}
i upgraded the line
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
//if you can see the fragment
}else{
//if you dont
}
}
to
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
//if you can see the fragment
}else{
//if you dont
imageViewToDelete.setImageDrawable(null); //this is ImageView from Fragment
}
}
REMEMBER:
setUserVisibleHint()
is set earlier than the onCreateView()
good luck
For each imageView you will have to call recycle()
method. So, before the line:
bild.setImageBitmap(DecodeImage.decode(bild.getContext().getResources(), R.drawable.swipe_bild));
You have to put the line:
((BitmapDrawable) bild.getDrawable()).getBitmap().recycle();
If the problem persists, it's because the image is too large and then you will have to compress it
I faced same problem and solved it, as follows
Best example is given in android developer guide, follow this guide step by step.
1.implement inJustDecodeBounds http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
2.Follow the below guide for asynchronous and caching, you can also download the sample from same link. http://developer.android.com/training/displaying-bitmaps/display-bitmap.html
I had OutOfMemory
error in ViewPager
with images (720*1200). Combining advices I found the solution, which worked for me:
put images into
drawable-nodpi
category (remove from all other drawable categories)decoding drawable into bitmap with options (inSampleSize = 1, ARGB_8888)
I was using Picasso and had this problem too... Just erase the dummy content you placed into the ImageView. Erase the src tag, as you won't need it with Picasso.
<ImageView
android:id="@+id/img"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
**android:src="@drawable/myDrawable"**/>
This happens because the drawables have to be loaded even if you replace them by Picasso afterward, and after you load many images into your ViewPager, it causes the OutOfMemory.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With