Search code examples
androidandroid-listfragment

Programmatically check (select) ListFragment item after screen rotation


I want to programmatically (re)highlight selected list item after screen rotation.

public class MyListFragment extends ListFragment {
    private static final String tag = MyListFragment.class.getName();
    private static final String indexTag = "index";
    private int index = -1;

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
        if (savedInstanceState != null) {
            index = savedInstanceState.getInt(indexTag, -1);
            Log.d(tag, "Restored index " + index + " from saved instance state.");
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        if (index >= 0) {
            showDetails(index);
        }
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        showDetails(position);
    }

    private void showDetails(int index) {
        this.index = index;
        getListView().setItemChecked(index, true);
        // update details panel
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt(indexTag, index);
    }
}

I use CheckedTextView as item view in my custom adapter:

public class MyListAdapter extends BaseAdapter {
    private static final String tag = MyListAdapter.class.getName();

    @Override
    public CheckedTextView getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null || !(convertView instanceof CheckedTextView)) {
            final LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.simple_list_item_single_choice, parent, false);
        }
        ((CheckedTextView)convertView).setText("test");
        return (CheckedTextView)convertView;
    }
}

After screen rotation showDetails() is called and details panel updates but setItemChecked()does nothing and the item is still not highlighted. Also I noticed that when item it clicked by touch event setItemChecked() is not needed and the row highlights anyway.

So how can I programmatically check the item during onResume stage?


Solution

  • I solved the problem. I forgot that I'm setting list adapter through AsyncTask on my activity so when showDetails() is called during onResume stage my fragment still has empty list.

    So I removed onResume method from my fragment, made showDetails() public and call it from my activity after setting the adapter:

        public void onListLoadDone(...) {
            final MyListAdapter adapter = new MyListAdapter(...);
            myListFragment.setListAdapter(adapter);
            myListFragment.showDetails();
        }