Question

Question

How do you save view widget instance state when, by using XML-defined widget layouts, components of the individual widget instances all have the same ID?

Example

Take, for example, the NumberPicker widget that's used in the TimePicker widget (note that NumberPicker is not exposed to the SDK). This is a simple widget with three components which are inflated from number_picker.xml: one increment button, one decrement button, and one EditText where you can directly enter a number. In order for the code to interact with these widgets, they all have IDs (R.id.increment, R.id.decrement and R.id.timepicker_input respectively).

Let's say you have three NumberPickers in an XML layout and you give them distinct IDs (eg. R.id.hour, R.id.minute).¹ This layout is then inflated to the content view of an activity. We decide to change the activity's orientation, so Activity.onSaveInstanceState(Bundle) helpfully saves our view state for each view that has an ID (this is the default behavior).

Unfortunately, the three NumberPickers have EditTexts that all share the same ID — R.id.timepicker_input. Thus, when the activity is restored, the one furthest down in the view hierarchy is the one whose state seems to be preserved for all three of them. Additionally, the focus goes to the first NumberPicker when restored regardless of which one had focus when saved.

TimePicker gets around this problem by preserving the state itself, separately. Unfortunately, this won't preserve the cursor position or the focused view without a lot more work. I'm not sure how it preserves that state if it does at all (and quickly playing with a time input dialog seems to indicate that it can somehow).

Please see the sample code to demonstrate this issue: https://github.com/xxv/AndroidNumberPickerBug


¹ In the view hierarchy, this sets the ID of the LinearLayout that NumberPicker extends to your IDs.

No correct solution

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top