2

I really can't make this up so I'd be thankful for any hint. I must make some mistake here (4.1.2).

I have an Activity which, in onCreate(), sets up a subclassed ArrayAdapter for ListView items which render as a Checkable ViewGroup.

The Activity already utilizes a NonConfiguration mechanism to re-build the Adapter upon orientation change. However, it's currently not storing the ListView's getCheckedItemPosition() because I feel it shouldn't be necessary (details below).

Interestingly, what I'm observing is the following.

  • The Activity is rendered.
  • The user checks a ListView item.
  • The ListView item is displayed in a checked state.
  • The onItemClickListener calls getCheckedItemPosition() for the ListView and gets a correct result.
  • The user changes the screen orientation.
  • onCreate() re-builds the 'ListView' and it displays just like before (after onCreate(); see below).
  • onCreate() calls getCheckedItemPosition() and gets -1 despite the ListView showing the correcly checked item

Upon further examination, the following details emerge.

  • onCreate():
    • get ListView resource
    • build MyAdapter
    • set MyAdapter as adapter for ListView
    • getCheckedItemPosition() returns -1
  • after onCreate():
    • MyAdapter.getView() is being called
    • CheckableViewGroup.setChecked() is called with the correct checked value
    • the last two steps will be repeated for all items

As said before, I'm relying on the Android feature that View objects save their state if they have an ID assigned. I'd say this is the case since there must be some object out there which sets the correct checked status for all the list entries. (By the way, CheckableViewGroup also overrides on{Save,Restore}InstanceState() but that won't be called regardless whether or not it has an ID assigned (presumably because it never gets attached to the layout root?).

So it looks as if the ListView at the same time knows and does not know its getCheckedItemPosition()? Or am I on the wrong track?

public final class MyActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.my_activity);
        itemList = (ListView)findViewById(R.id.ma_list);
        listAdapter = new MyAdapter();
        itemList.setAdapter(listAdapter);
        itemList.setOnItemClickListener(
            new OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> av, View v, int pos, long id) { checkForm(); }
            }
        );
        listAdapterSetup();
        // this is where itemList.getCheckedItemPosition() returns -1
        // when the listView has been re-built from NonConfiguration data:
        checkForm(); 
    }
}
class stacker
  • 5,357
  • 2
  • 32
  • 65

1 Answers1

1

I was making another test after I posted my question, because I was getting an idea while describing my observations.

And indeed, my suspicion was confirmed.

Timing is key here.

The ListView will report the correct getCheckedItemPosition() value in onResume() (but not before).

So the solution is easy: Perform any evaluation logic in onResume().

class stacker
  • 5,357
  • 2
  • 32
  • 65