Problem with onRetainNonConfigurationInstance
- by David
I am writing a small app using the Android SDK, 1.6 target, and the Eclipse plug-in. I have layouts for both portrait and landscape mode, and most everything is working well. I say most because I am having issues with the orientation change. One part of the app has a ListView "on top of" another section. That section consists of 4 checkboxes, a button, and some TextViews. That is the portrait version. The landscape version replaces the ListView with a Spinner and rearranges some of the other components (but leaves the ALL resource ids the same). While in either orientation things work like they should. It's when the app switches orientation that things go off. Only 1 of the checkboxes maintains it's state throughout both layout changes. The other three CBs only maintain their state when going from landscape-portrait. I am also having problem getting the ListView/Spinner to correctly set themselves on changing.
I am using onRetainNonConfigurationInstance() and creating a custom object that is returned. When I step through the code during a orientation change, the custom object is successfully pulled back out the the ether, and the widgets are being set to the correct values (inspecting them). But for some reason, once the onCreate is done, the checkboxes are not set to true.
public class SkillSelectionActivity extends Activity
{
private Button rollDiceButton;
private ListView skillListView;
private CheckBox makeCommonCB;
private CheckBox useEdgeCB;
private CheckBox useSpecializationCB;
private CheckBox isExtendedCB;
private TextView skillNameView;
private TextView skillRanksView;
private TextView rollResultView;
private TextView rollSuccessesView;
private TextView rollFailuresView;
private TextView extendedTestTotalView;
private TextView extendedTestTimeView;
private TextView skillSpecNameView;
private int extendedTestTotal = 0;
private int extendedTestTime = 0;
private Skill currentSkill;
private int currentPosition = 0;
private SRCharacter character;
private int skillSelectionType;
private Spinner skillSpinnerView;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.skill_selection2);
Intent intent = getIntent();
Bundle extras = intent.getExtras();
skillSelectionType = extras.getInt("SKILL_SELECTION");
skillListView = (ListView) findViewById(R.id.skillList);
skillSpinnerView = (Spinner) findViewById(R.id.skillSpinner);
rollDiceButton = (Button) findViewById(R.id.rollDiceButton);
makeCommonCB = (CheckBox) findViewById(R.id.makeCommonCB);
useEdgeCB = (CheckBox) findViewById(R.id.useEdgeCB);
useSpecializationCB = (CheckBox) findViewById(R.id.useSpecializationCB);
isExtendedCB = (CheckBox) findViewById(R.id.extendedTestCB);
skillNameView = (TextView) findViewById(R.id.skillName);
skillRanksView = (TextView) findViewById(R.id.skillRanks);
rollResultView = (TextView) findViewById(R.id.rollResult);
rollSuccessesView = (TextView) findViewById(R.id.rollSuccesses);
rollFailuresView = (TextView) findViewById(R.id.rollFailures);
extendedTestTotalView = (TextView) findViewById(R.id.extendedTestTotal);
extendedTestTimeView = (TextView) findViewById(R.id.extendedTestTime);
skillSpecNameView = (TextView) findViewById(R.id.skillSpecName);
character = ((SR4DR) getApplication()).getCharacter();
ConfigSaver data = (ConfigSaver) getLastNonConfigurationInstance();
if (data == null)
{
makeCommonCB.setChecked(false);
useEdgeCB.setChecked(false);
useSpecializationCB.setChecked(false);
isExtendedCB.setChecked(false);
currentSkill = null;
}
else
{
currentSkill = data.getSkill();
currentPosition = data.getPosition();
useEdgeCB.setChecked(data.isEdge());
useSpecializationCB.setChecked(data.isSpec());
isExtendedCB.setChecked(data.isExtended());
makeCommonCB.setChecked(data.isCommon());
if (skillSpinnerView != null)
{
skillSpinnerView.setSelection(currentPosition);
}
if (skillListView != null)
{
skillListView.setSelection(currentPosition);
}
}
// Register handler for UI elements
rollDiceButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
// guts removed for clarity
}
});
makeCommonCB.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
// guts removed for clarity
}
});
isExtendedCB.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
// guts removed for clarity
}
});
useEdgeCB.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
// guts removed for clarity
}
});
useSpecializationCB.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
// guts removed for clarity
}
});
if (skillListView != null)
{
skillListView.setOnItemClickListener(new OnItemClickListener()
{
@Override
public void onItemClick(AdapterView<?> parent, View v, int position, long id)
{
// guts removed for clarity
}
});
}
if (skillSpinnerView != null)
{
skillSpinnerView.setOnItemSelectedListener(new MyOnItemSelectedListener());
}
populateSkillList();
}
private void populateSkillList()
{
String[] list = character.getSkillNames(skillSelectionType);
if (list == null)
{
list = new String[0];
}
if (skillListView != null)
{
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.list_item, list);
skillListView.setAdapter(adapter);
}
if (skillSpinnerView != null)
{
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, list);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
skillSpinnerView.setAdapter(adapter);
}
}
public class MyOnItemSelectedListener implements OnItemSelectedListener
{
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
{
// guts removed for clarity
}
public void onNothingSelected(AdapterView<?> parent)
{
// Do nothing.
}
}
@Override
public Object onRetainNonConfigurationInstance()
{
ConfigSaver cs = new ConfigSaver(currentSkill, currentPosition, useEdgeCB.isChecked(), useSpecializationCB.isChecked(), makeCommonCB.isChecked(), isExtendedCB.isChecked());
return cs;
}
class ConfigSaver
{
private Skill skill = null;
private int position = 0;
private boolean edge;
private boolean spec;
private boolean common;
private boolean extended;
public ConfigSaver(Skill skill, int position, boolean useEdge, boolean useSpec, boolean isCommon, boolean isExt)
{
this.setSkill(skill);
this.position = position;
this.edge = useEdge;
this.spec = useSpec;
this.common = isCommon;
this.extended = isExt;
}
// public getters and setters removed for clarity
}
}