12

我遇到了一个相当大的 GridView 的问题。(大约 70 个孩子)如果我在 onCreate 上启动它或在按下主页按钮然后返回后恢复,GridView 工作正常。但是当我从睡眠模式恢复后恢复时,我的 BaseAdapter 再次启动并破坏了我在运行时对其所做的更改。如果我在重新启动后调用它,这也会使 getChildAt() 给出 NullPointerException。

我怎样才能让它只做常规的 onPause(home button) 对 GridView 所做的事情,并避免每次从睡眠模式恢复时 GridView 都被清除?

编辑:我尝试为调用 BaseAdpter 的 Activity 类设置唤醒锁,但没有成功

2.编辑:自从我发布这个问题以来,我一直在尝试使用 onPause 中的代码恢复 GridView:

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

这在 onResume 中:

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

    }

奇怪的是我似乎在屏幕上从一个地方跳到另一个地方,当我尝试 getChildAt() 时它仍然崩溃。在睡眠模式后也无法获得它。

  1. 编辑这是来自 BaseAdapter getView 的代码(注意!其中一些代码无关紧要)

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;

}

并在 onCreate 中定义 GridView:

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

我在你的代码中注意到一件事:

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

即使GridView是 a ViewGroup,您也无法访问它的LayoutParams。想一想,如果这可能,这意味着您可以将 aGridView放入 anotherGridView中。

在更进一步之前解决这个问题,因为它会惹恼你。

例如,如果您希望 GridView 位于 LinearLayout 中,请尝试以下操作:

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

这是此答案的正确实现:

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

尝试使用这个标签:

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

您可以使用onSaveInstanceState (Bundle outState) 来保存您的网格视图的状态

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

然后在将适配器设置为 grdiview 后在onCreate中添加此代码

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

您的应用程序是否在横向模式下运行?

如果是,那么您应该考虑添加标签

"android:configChanges="keyboard|keyboardHidden|orientation"用于 Manifest.xml 中的活动,这将防止 android 系统在您解锁屏幕时杀死您的活动并重新启动它。

于 2012-12-18T07:38:11.240 回答