12

I got a problem with a quite large GridView.(about 70 children) The GridView works fine if I start it on onCreate or after resumeing after pressing the home button and then return. But when I resume after coming back from sleep mode, my BaseAdapter starts again and ruin the changes I have done to it during runtime. This also make getChildAt() give a NullPointerException if I am calling it just after restart.

How can I make it just do what regular onPause(home button) does to the GridView, and avoid that the GridView is wiped out everytime I am resumeing from sleep mode?

Edit: I have tried setting a wakelock for my Activity class that calls the BaseAdpter with no luck

2.Edit: Since I posted this question I have played around with trying to restore the GridView using this code in onPause:

 SparseArray<Parcelable> array = new SparseArray<Parcelable>();
    gridView.saveHierarchyState(array);
    bundle = new Bundle();
    bundle.putSparseParcelableArray("state", array);

And this in onResume:

 try{
    gridView.restoreHierarchyState(bundle.getSparseParcelableArray("state"));
    }
    catch(Exception e){
        //Most likely first start
        Log.i("SomeTag", "No GridView state found");
    }

    }

The strange thing is everything I seems to have jumped from one place to another on the screen and it is still crashing when I try to getChildAt(). It is also failing to get it after sleep mode.

  1. Edit Here is the code from BaseAdapter getView(Note! some of this code is irrelevant)

public View getView (int position, View convertView, ViewGroup parent) {

mParentView = parent;


DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();
int width = metrics.widthPixels;
int height = metrics.heightPixels;

    //sets the height for every individual box
int box = width/7*6/10;

ImageCell v = null;
if (convertView == null) {
    // If it's not recycled, create a new ImageCell.
    v = new ImageCell (mContext);
    v.setLayoutParams(new GridView.LayoutParams(box, box));
    v.setScaleType(ImageView.ScaleType.CENTER_CROP);
    v.setPadding(0, 0, 0, 0);


} else {
    v = (ImageCell) convertView;
}

v.mCellNumber = position;
v.mGrid = (GridView) mParentView;
v.mEmpty = true;
int id = 200;
v.setId(++id);

String map = str[position];
int pos = position;
int up = pos-10;
int down = pos+10;
int left = pos-1;
int right = pos+1;
if(up>=0){
above = str[up];
}
else{
    //Do nothing
}
if(down<70){
    under = str[down];
    }
else{
    //Do nothing
}
if(left<=-1){
   //Do nothing
}

else{
    lefte=str[left];
}
if(right>=70){
    //Do nothing
 }     
 else{
    righte=str[right];
 }
//if(left>-1|left!=9|left!=19|left!=29|left!=39|left!=49|left!=59){
   // lefte = str[left];
  //  }
 // else{
 //     Log.i("ImageCellAdapter", "Left is trying to break walls "+left);
    //Do nothing
  // }


if (map.equals("mountain")) {
    //Checks surroundings to find out witch drawable to set  
    v.setBackgroundResource(R.color.cell_empty);
     v.mEmpty = false;
     //All
     if(above=="mountain"&&under=="mountain"&&lefte=="mountain"&&righte=="mountain"){
            v.setImageResource(R.drawable.mountain_full);
        }
     //Single
     else if(above=="mountain"&&under!="mountain"&&lefte!="mountain"&&righte!="mountain"){
            v.setImageResource(R.drawable.mountain_down);
        }
     else if(above!="mountain"&&under=="mountain"&&lefte!="mountain"&&righte!="mountain"){
            v.setImageResource(R.drawable.mountain_up);
        }
     else if(above!="mountain"&&under!="mountain"&&lefte!="mountain"&&righte=="mountain"){
            v.setImageResource(R.drawable.mountain_left);
        }
     else if(above!="mountain"&&under!="mountain"&&lefte=="mountain"&&righte!="mountain"){
            v.setImageResource(R.drawable.mountain_right);
        }
     //Double
     else if(above=="mountain"&&under!="mountain"&&lefte!="mountain"&&righte=="mountain"){
            v.setImageResource(R.drawable.mountain_left_down);
        }
     else if(above!="mountain"&&under=="mountain"&&lefte!="mountain"&&righte=="mountain"){
            v.setImageResource(R.drawable.mountain_left_up);
        }
     else if(above=="mountain"&&under!="mountain"&&lefte=="mountain"&&righte!="mountain"){
            v.setImageResource(R.drawable.mountain_right_down);
        }
     else if(above!="mountain"&&under=="mountain"&&lefte=="mountain"&&righte!="mountain"){
            v.setImageResource(R.drawable.mountain_up_right);
        }
     else if(above!="mountain"&&under!="mountain"&&lefte=="mountain"&&righte=="mountain"){
            v.setImageResource(R.drawable.mountain_up_down);
        }
     else if(above=="mountain"&&under=="mountain"&&lefte!="mountain"&&righte!="mountain"){
            v.setImageResource(R.drawable.mountain_up_down);
        }
     //Triple
     else if(above!="mountain"&&under=="mountain"&&lefte=="mountain"&&righte=="mountain"){
            v.setImageResource(R.drawable.mountain_left_right_down);
        }
     else if(above=="mountain"&&under=="mountain"&&lefte=="mountain"&&righte!="mountain"){
            v.setImageResource(R.drawable.mountain_left_up_down);
        }
     else if(above=="mountain"&&under!="mountain"&&lefte=="mountain"&&righte=="mountain"){
            v.setImageResource(R.drawable.mountain_left_up_right);
        }
     else if(above=="mountain"&&under=="mountain"&&lefte!="mountain"&&righte=="mountain"){
            v.setImageResource(R.drawable.mountain_up_right_down);
        }
     //None
        else{
    v.setImageResource(R.drawable.mountain);
        }

}
else if(map=="start"){
    List<String> posOf = Arrays.asList(str);
    startPos=posOf.indexOf("start");
    v.mEmpty=false;
    v.setBackgroundResource(R.color.cell_empty);
    getDur();

     BitmapDrawable first = (BitmapDrawable)mContext.getResources().getDrawable(R.drawable.gress);
     BitmapDrawable second =(BitmapDrawable)mContext.getResources().getDrawable(R.drawable.ic_launcher);
     BitmapDrawable third = (BitmapDrawable)mContext.getResources().getDrawable(R.drawable.gress);
     BitmapDrawable fourth = (BitmapDrawable)mContext.getResources().getDrawable(R.drawable.ic_launcher);

    final AnimationDrawable ani = new AnimationDrawable();       
       ani.addFrame(first, duration);
       ani.addFrame(second, duration);
       ani.addFrame(third, duration);
       ani.addFrame(fourth, duration);
       ani.setOneShot(true);
     v.setImageDrawable(ani);        
       checkIfAnimationDone(ani); 
    v.post(new Runnable() {   
        public void run() {
               ani.start();
                }
        });
}
else if(map=="stop"){
    v.mEmpty=false;
    v.setBackgroundResource(R.color.cell_empty);
    v.setImageResource(R.drawable.ic_launcher);
    v.setTag(1);
}
else if(map=="grass"){
    v.mEmpty=false;
    v.setBackgroundResource(R.drawable.gress);


}
else{
   //    v.setBackgroundResource (R.color.drop_target_enabled);
v.setBackgroundResource (R.color.cell_empty);
}
//v.mGrid.requestDisallowInterceptTouchEvent (true);

//v.setImageResource (R.drawable.hello);

// Set up to relay events to the activity.
// The activity decides which events trigger drag operations.
// Activities like the Android Launcher require a long click to get a drag operation started.


return v;

}

And defining the GridView in onCreate:

gridView= new BoxView(this);

        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH){

              w.getDefaultDisplay().getSize(size);

              Measuredwidth = size.x;
              Measuredheight = size.y; 
            }else{
              Display d = w.getDefaultDisplay(); 
              Measuredwidth = d.getWidth(); 
              Measuredheight = d.getHeight(); 
            }
        int width = Measuredwidth/7*6;

    gridView.setLayoutParams(new GridView.LayoutParams(width,LayoutParams.FILL_PARENT, Gravity.CENTER_HORIZONTAL));
    gridView.setNumColumns(columns);
    gridView.setVerticalSpacing(0);
    gridView.setHorizontalSpacing(0);
    gridView.setPadding(0, 0, 0, 0);
    gridView.setId(101);
    gridView.setSelector(android.R.color.transparent);
    gridView.setAdapter (new ImageCellAdapter(this, MAP));
4

4 に答える 4

4

I have noticed one thing in you code:

gridView.setLayoutParams(new GridView.LayoutParams(width,LayoutParams.FILL_PARENT, Gravity.CENTER_HORIZONTAL));

Even if GridView is a ViewGroup, you can't access it's LayoutParams. Just think it trough, if this would be possible that means you could put a GridView inside another GridView.

Fix this before going further because is messing with you.

If you want your GridView to be inside a LinearLayout, for example, try this:

gridView.setLayoutParams(new LinearLayout.LayoutParams(width,LayoutParams.FILL_PARENT, Gravity.CENTER_HORIZONTAL));

Here is the correct implementation of this answer:

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        /*You have to implement what things from the gridView sould be "saved"*/
        GridView gridView = new GridView(this) {

            @Override
            public Parcelable onSaveInstanceState() {
                // Create the Parceable object with the things you want to save
                                Parceable stateOfGrid = ....etc
                return stateOfGrid;
            }

                        @Override
            public void onRestoreInstanceState(Parcelable state) {
                // Restore your grid's parameters that you previously implemented in onSaveInstanceState
                super.onRestoreInstanceState(state);
                                ...
            }

        };

    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onRestoreInstanceState(savedInstanceState);

                if (savedInstanceState != null) {
                    Parcelable state = savedInstanceState.getParcelable("state");
                    if (state != null) {
                        gridView.onRestoreInstanceState(state);
                        Log.d(this.getClass().getName(), "state restored!");                
                    }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        // Put your grid's Parceable into the bundle
        super.onSaveInstanceState(outState);
                Parcelable state = gridView.onSaveInstanceState();
                outState.putParcelable("state", state);
    }


}
于 2012-12-05T18:46:28.680 に答える
2

Try using this tag:

android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
于 2012-12-19T09:52:34.577 に答える
1

You can use onSaveInstanceState (Bundle outState) to save state of your gridview

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    Parcelable state = gridView.onSaveInstanceState();
    outState.putParcelable("state", state);
}

then in onCreate after you seted adapter to grdiview add this code

if (savedInstanceState != null) {
  Parcelable state = savedInstanceState.getParcelable("state");
  if (state != null) {
    gridView.onRestoreInstanceState(state);
    Log.d(this.getClass().getName(), "state restored!");                
  }
}
于 2012-12-03T18:59:59.813 に答える
0

Is your application running in Landscape Mode?

if yes, then you should consider adding the tag

"android:configChanges="keyboard|keyboardHidden|orientation" for your activity in Manifest.xml, which will prevent android system from killing your activity and restarting it when you unlock the screen.

于 2012-12-18T07:38:11.240 に答える