02.03.2011 16:23, Thierry Legras пишет:
(putting again CC to android as your answer seems quite usefull to
android community!)
Thank you. I meant to reply to the list, but Thunderbird sometimes has
other ideas :) And good luck to you with resolving the issue.
Wow, thanks Kostya, I am impressed by this so detailed answer :).
Answers inline.
2011/3/2 Kostya Vasilyev <[email protected] <mailto:[email protected]>>
Yes, if the activity isn't getting recreated, there won't be
onRestoreInstanceState due to activity lifecycle. However it can
still be called on the spinner view under certain conditions.
For a cursor-based adapter, a managed cursor gets closed/reopened
when the activity is paused / resumed, which causes the data set
to be invalidated.
AdapterView saves and restores selection state when that happens,
by calling onSaveInstanceState / onRestoreInstanceState on itself:
see AdapterDataSetObserver in AdapterView.java.
Selection state *can* be delivered asynchronously, when an adapter
view is undergoing a layout: see SelectionNotifier in the same
source file. That's another possibility, that the spinner is
undergoing a layout, and actually, AdapterView does request layout
when the data set changes - so we're back to the question of, what
kind of adapter are you using for the spinner?
Indeed, my spinner use a SimpleCursorAdapter. It seems in my case, the
view is underoing a layout after selected tab has been changed and the
new view containing the spinner needs to be drawn.
A couple practical things to try that came to my mind are:
1 - Post selection change from Activity B to tab1 asynchronously,
using a Handler, after calling setCurrentTab;
If this works, this would be a neat solution as it will clearly keep
separated activites code.
I will definitively try that instead of my dirty flag trick, thanks :-)
2 - If tab activities have onResume called when switched (I
haven't used tabs, so don't know) ...
Not in my case as tab 1 content is not an activity but only a view. so
when I select tab 2, Activity A (which is the TabActivity) does not
pause, but stay actives.
... - you could set the new selection state as a member variable
in tab1, and set the new selection in its onResume (probably after
calling the base class).
Finally, as a side note, this falls into the 0,01% of bugs for
which it's very useful to have Android framework sources installed
in the Eclipse debugger. I have detailed instructions in my blog,
under tools - it recently really helped me resolve a similar bug
caused by interference with that very same code in AdapterView.
Thanks again for this tip!
BTW your blog looks like a goldmine to me, I think I will re-use your
IP address EditText :)
Thierry.
-- Kostya
02.03.2011 14:21, Thierry Legras пишет:
Hi Kostya,
Thanks to try to help to sort this out. unfortunatly I don't
think this is the cause in this case:
Activity A is a TabActivity that embeds activity B being in tab
2. Indeed when I select tab 1 from activity B using
setCurrentTabByTag , _Activity A is already in running state_ (I
checked onResume was called earlier), so I dont think
onRestoreInstanceState will be called here.
Also I tried to place a breakpoint in onItemSelected, but this
was no help, it seems to be triggered using runOnUIThread() or
similar.
But on the idea, you are probably close. It seems Android is
trying to restore an old state (spinner position). Either this is
a bug, or I did not correctly used setSelection. I am wondering
if calling setPosition from another activity is a safe pratice??
Thierry.
2011/3/2 Kostya Vasilyev <[email protected]
<mailto:[email protected]>>
Thierry,
I think you are seeing interaction between the activity's
onRestoreInstanceState and your setSelection.
Should be pretty easy to check by overriding
onRestoreInstanceState in ActivityA and/or the spinner and
logging them - as well as your code that calls setSelection.
Then you can re-run both scenarios from your original email
and watch the exact sequence of events.
-- Kostya
02.03.2011 12:52, Thierry Legras пишет:
Okay, as I could not find a way to fix that smoothly, I just
used a flag ignoreNextOnItemSelected like described
hereafter. Seems to me a dirty hack :(
// called from another activity context
updateSpinnerSelection(int newposition) {
mPosition = newposition; // store it
mSpinner.setSelection(newposition);
ignoreNextOnItemSelected= true;
}
and
public void onItemSelected(AdapterView<?> arg0, View arg1,
int position,
long rowid) {
if (ignoreNextOnItemSelected) {
// position might be outdate ?!?! just reapply mPosition
ignoreNextOnItemSelected = false;
// required
mSpinner.setSelection(mPosition);
} else {
mPosition = position;
... // do usual stuff
}
}
2011/2/25 Thierry Legras <[email protected]
<mailto:[email protected]>>
Hi,
I have a strange behavior in a very specific case and
wonder if the issue comes from my code or not.
I have a TabActivity A with 2 tabs:
- Tab 1 content is created as a view with a spinner in it
- Tab 2 content is an activity B.
I want at some point when Tab2 is selected to switch to
Tab 1 and update spinner selection in it.
Case 1)
Tab 2 is selected, from Activity B context:
activityA.updateSpinnerSelection(newposition);
activityA.getTabHost().setCurrentTabByTag(tab1tag);
later AdapterView.OnItemSelectedListener.onItemSelected
is called with my newposition
=> so this /usually /works fine:
Case 2)
Tab 2 is selected, from Activity B context, but before
doing the same things, if the users for some reason
*first open a new acticity C on top of B (like
preference screen) and close this activity C*, (so A and
B are paused then resumed), then if I later try again
the same things:
activityA.updateSpinnerSelection(newposition);
activityA.getTabHost().setCurrentTabByTag(tab1tag);
so far so goog, but later
AdapterView.OnItemSelectedListener.onItemSelected is
called not with newposition as argument *but with the
older position value*.
I hope the description is clear.
Did I missed something? or could this behavior dues to
some bug in Android?
Thanks for any help,
--
Thierry.
--
Thierry.
--
You received this message because you are subscribed to the
Google
Groups "Android Developers" group.
To post to this group, send email to
[email protected]
<mailto:[email protected]>
To unsubscribe from this group, send email to
[email protected]
<mailto:[email protected]>
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
--
Kostya Vasilyev --http://kmansoft.wordpress.com
--
You received this message because you are subscribed to the
Google
Groups "Android Developers" group.
To post to this group, send email to
[email protected]
<mailto:[email protected]>
To unsubscribe from this group, send email to
[email protected]
<mailto:android-developers%[email protected]>
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
--
Thierry.
--
Kostya Vasilyev --http://kmansoft.wordpress.com
--
Thierry.
--
Kostya Vasilyev -- http://kmansoft.wordpress.com
--
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en