1

I have a Gallery which allows users to browse a gallery, select an image as their choice, and continue to browse the gallery without changing that selection. This works by using onItemSelected to see if the image they are selecting (ie, with a click) is the image already selected (by the gallery's motion). So:

  1. User moves forward and back through Gallery.
  2. User decides on their favoured image and centres the Gallery on it.
  3. User clicks the image, it gets "selected" and is given a green border.
  4. User can continue to move forward and back in the Gallery, without the currently centred image automatically being "selected".

This is fine. However, I am now trying to allow orientation changes while selecting an image, and what I have found is that onItemSelected is called on the Gallery after all the onConfigChanged code has executed.

So onConfigChange I set parameters (ie, what index the Gallery was on before orientation change), and then I call my initialiseUI method. This executes successfully and sets up everything it needs to, including positioning the Gallery at the same index it was positioned at before the orientation change. But then onItemSelected is called, on the centred image. This causes the centred image to be selected as their choice (green border etc), without the user clicking on it.

I have tried using a Boolean flag, "configIsChanging", to only execute the onItemSelected code when configIsChanging is false. Unfortunately, this doesn't seem to work, as onItemSelected is called after onConfigChange completes, and by that point the flag has been reset to false.

@Override
public void onConfigurationChanged(Configuration newConfig) {
    configChanging = true; 

    tempConfigDisplayedIndex = mGallery.getSelectedItemPosition(); 

    super.onConfigurationChanged(newConfig);

    setContentView(R.layout.take_questionnaire);

    initialiseUI(); 
    configChanging = false; 
}

Has anyone had any experience with rogue onItemSelected events? Any ideas? I can post more code if required. Many thanks for any help.

Comic Sans MS Lover
  • 1,729
  • 5
  • 26
  • 52
breadbin
  • 584
  • 1
  • 11
  • 19

3 Answers3

3

have you tried just putting android:configChanges="orientation" in your manifest?

josephus
  • 8,284
  • 1
  • 37
  • 57
  • Yes, I've done that, but my Activity is more complex than the code above explains. It iterates through a number of "questions", each with a set of images as potential answers, and a user must select one for each question. Unless I handle the configuration change in my code, then an orientation change brings the user back to the first question. – breadbin Apr 16 '12 at 11:19
  • i understand the cause of the issue, but these might help you debug better: http://developer.android.com/guide/topics/manifest/activity-element.html#config and http://stackoverflow.com/questions/456211/activity-restart-on-rotation-android. the idea is to use onSavedInstanceState on onRetainNonConfigurationState – josephus Apr 16 '12 at 11:29
1

Can't you put your boolean (maybe a field) in your onResume/onCreate?

configIsChanging = true; In your 2 methods onPause and onResume.

@Override    
public void onConfigurationChanged(Configuration newConfig)
{
   if(!configIsChanging){
       tempConfigDisplayedIndex = mGallery.getSelectedItemPosition(); 

       super.onConfigurationChanged(newConfig);

       setContentView(R.layout.take_questionnaire);

       initialiseUI(); 
   }else{
       configIsChanging = false;
   }
}

This works for me.

Comic Sans MS Lover
  • 1,729
  • 5
  • 26
  • 52
  • That helps! Now it works for first config change, but same problem as before for any subsequent config changes. Above, you mention "onResume/onCreate" and then on next line "onPause and onResume" - did you mean onCreate, or onPause, or both? – breadbin Apr 16 '12 at 13:33
  • Ok, I got it working. Had to change a few things. Stack won't let me answer my own question for another 5 hrs because I have < 100 reputation, but I'll put up the solution tomorrow for anyone who wants it. – breadbin Apr 16 '12 at 14:04
  • Yeh I made confusion, it was meant onResume and onCreate, sorry. But good thing it worked for you =] You should edit your question with the answer until you can post the answer. – Comic Sans MS Lover Apr 16 '12 at 14:14
0

Following on from @Gabriel's answer, I have solved the problem using the following code snippets. It's slightly different from Gabriel's code, and I've left out the bits no one else will care about :)

@Override
protected void onResume() {
    super.onResume();       
    configChanging = true; 
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
if (mAdapter.selectedIndex > -1) { 
    tempConfigSelectedIndex = mAdapter.selectedIndex;
}

super.onConfigurationChanged(newConfig);
if (configChanging) {
    tempConfigDisplayedIndex = mGallery.getSelectedItemPosition(); 

    setContentView(R.layout.take_questionnaire);

    initialiseUI();
}
}

@Override
public void onItemSelected(AdapterView<?> parent, View v, int position, long id) {

if (!configChanging){
    // code here to execute only when user clicks
}
configChanging = false; 
// code here to execute when either user clicks OR config is changed
}
breadbin
  • 584
  • 1
  • 11
  • 19