June
June

Reputation: 265

CheckBoxes in ListView disappear when the screen rotates

What my application first does is it loads ListView whose items have invisible CheckBoxes by setting its visibility View.Gone. When the user tabs a menu button then it will turn on and off the CheckBox visibility and some other layouts. Below is the code, I removed some unnecessary parts:

private void editmodeSwitch(boolean flag){
    // get topbar, bottombar, and bottombar2
    LinearLayout topbar = (LinearLayout) findViewById(R.id.task_topbar_linearLayout);
    LinearLayout bottombar = (LinearLayout) findViewById(R.id.task_bottombar1_linearlayout);
    LinearLayout bottombar2 = (LinearLayout) findViewById(R.id.task_bottombar2_linearlayout);

    if(flag){
        isEditmodeOn = true;            

        // make topbar and bottombar2 visilble, but bottombar gone
        topbar.setVisibility(View.VISIBLE);
        bottombar.setVisibility(View.GONE);
        bottombar2.setVisibility(View.VISIBLE);

        // make checkboxes visible in listview visible as well
        for(int i=0; i<listView.getChildCount(); i++){
            LinearLayout ll = (LinearLayout) listView.getChildAt(i);
            CheckBox cb = (CheckBox) ll.findViewById(R.id.task_row_checkBox1);
            cb.setVisibility(View.VISIBLE);
        }
    }
    else{
        isEditmodeOn = false;

        topbar.setVisibility(View.GONE);
        bottombar.setVisibility(View.VISIBLE);
        bottombar2.setVisibility(View.GONE);

        // set each checkbox false and its visibility gone
        for(int i=0; i<listView.getChildCount(); i++){
            LinearLayout ll = (LinearLayout) listView.getChildAt(i);
            CheckBox cb = (CheckBox) ll.findViewById(R.id.task_row_checkBox1);
            cb.setVisibility(View.GONE);
            cb.setChecked(false);
        }
    }
}

It works fine but the problem is the application doesn't work when the screen rotates(changes the screen orientation). Everything worked fine as it displayed some layouts but only CheckBoxes in list items. Below is the code inonCreate()`:

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

    initialize();
    loadDB();
    updateListAdapter(list_title, list_date);

    // in case of screen rotation
    if(savedInstanceState != null){
        isEditmodeOn = savedInstanceState.getBoolean(EDITMODE_CHECK);
        isItemChecked = savedInstanceState.getBoolean(ITEM_CHECK);

        if(isEditmodeOn){
            if(!isItemChecked){
                Log.i(tag, "item NOT checked");
                editmodeSwitch(true);
            } else{
                //this is something different so please don't mind
                deditmodeSwitch(savedInstanceState.getBooleanArray(LIST_CB_CHECK));
            }
        }
    }
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

    // save values for rotation
    outState.putBoolean(EDITMODE_CHECK, isEditmodeOn);
    outState.putBoolean(ITEM_CHECK, isItemChecked);
    outState.putBooleanArray(LIST_CB_CHECK, list_cb_check);
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    Log.i(tag, "you're in onRestoreInstanceState()");

    // in case of screen rotation
    if(savedInstanceState != null){
        isEditmodeOn = savedInstanceState.getBoolean(EDITMODE_CHECK);
        isItemChecked = savedInstanceState.getBoolean(ITEM_CHECK);

        if(isEditmodeOn){
            if(!isItemChecked){
                Log.i(tag, "item NOT checked");
                editmodeSwitch(true);
            } else{
                // this is for something else so please ignore this part
                editmodeSwitch(savedInstanceState.getBooleanArray(LIST_CB_CHECK));
            }
        }
    }

What I guessed is the ListView is being loaded at the end. Therefore, even if the code in onCreate() makes CheckBoxes visible, the CheckBoxes will become invisible again as its initialization in xml will do so. However, I'm stuck here and need your advice to solve this problem. Can anyone help me?

Just in case, below is the checkbox code of layout xml file for getview.

<CheckBox android:id="@+id/task_row_checkBox1" android:gravity="right" 
    android:layout_width="wrap_content" android:layout_height="wrap_content" 
    android:visibility="gone"
    />

Upvotes: 1

Views: 2906

Answers (3)

June
June

Reputation: 265

Based on my experience, getview seems to be triggered at the end and it was why 'onRestoreInstanceState()' and 'onConfigurationChanged()' could not make it as getview will reset my checkboxes invisible as initialization in the layout xml file.

Therefore, the only solution I could find out was I must control them in getview for the answer.

Upvotes: 0

Gophermofur
Gophermofur

Reputation: 2101

Similar to how you override onCreate, you can override onConfigurationChanged(...) which you can setup to run when the screen changes orientation.

In order for OnConfigurationChanged(...) to be trigger when the screen rotates, you need to to edit your manifest and put that relationship/rule in.

It's easy to do but takes a bit of explaining and it was answered before in this question: Activity restart on rotation Android

Edit: Here is the dev guide on how to handle configuration changes http://developer.android.com/guide/topics/resources/runtime-changes.html

Edit #2: First, let me suggest using Imran's solution. It follows the Developer Guide better and the end results will be the same.

Now, for the onConfigurationChanged solution.

Look at what you are doing with your onCreate:

1) Set the view. (Checkboxes are hidden at this point. Right?)

2) Call your DB and determine if you should display checkboxes (edit mode)

3) Make all the checkboxes visible.

Now, onConfigurationChanged also calls setContentView, at which point all your checkboxes are hidden again. So you need to repeat the process of making your checkboxes visible (#3 above). You probably don't need to repeat step #2 because the value should be retained, but I'm not sure how the logic of your app works, so you may need to re-do step #2.

Does that make sense?

Upvotes: 0

ρяσѕρєя K
ρяσѕρєя K

Reputation: 132982

Override onSaveInstanceState for saving value on screen rotation and onRestoreInstanceState as:

protected void onCreate(Bundle savedInstanceState) {

    if(null != savedInstanceState)
            {
                Boolean IntTest = savedInstanceState.getBoolean("ITEM_CHECK");
                Boolean StrTest = savedInstanceState.getBoolean("ITEM_CHECK");
                Log.e(TAG, "onCreate get the   savedInstanceState+IntTest="+IntTest+"+StrTest="+StrTest);        
            }
}
        @Override
        public void onSaveInstanceState(Bundle savedInstanceState) {
            // Save away the CheckBoxes states, so we still have it if the activity
            // needs to be killed while paused.

          savedInstanceState.putBoolean(EDITMODE_CHECK, 0);
          savedInstanceState.putBoolean(ITEM_CHECK, 0);
          super.onSaveInstanceState(savedInstanceState);
          Log.e(TAG, "onSaveInstanceState");
        } 
        @Override
        public void onRestoreInstanceState(Bundle savedInstanceState) {
          super.onRestoreInstanceState(savedInstanceState);
          Boolean IntTest = savedInstanceState.getBoolean(EDITMODE_CHECK);
          Boolean StrTest = savedInstanceState.getBoolean(ITEM_CHECK);
          Log.e(TAG, "onRestoreInstanceState+IntTest="+IntTest+"+StrTest="+StrTest);
        }

Upvotes: 1

Related Questions