saving state on compound view widgets
-
30-10-2019 - |
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 NumberPicker
s 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 NumberPicker
s have EditText
s 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