0

First off, I've already looked at this question. In my scenario, I have a fragment that extends support.v4.app.ListFragment. The fragment calls a custom adapter. I need to handle orientation changes on a device that will switch to a 2 pane layout. I believe I'm doing most things right as the view itself changes correctly and I am able to retrieve the data from savedInstanceState. However, my list is always empty. I tried the recommended answer in the linked question (calling setListShown(true)), but I get an exception, "Can't be used with a custom content view". The relevant code is below:

@Override
public void onConfigurationChanged(Configuration newConfig){
    super.onConfigurationChanged(newConfig);

    LayoutInflater inflater = LayoutInflater.from(getActivity());
    ViewGroup group = ((ViewGroup) getView());
    group.removeAllViews();
    inflater.inflate(R.layout.activity_message_list, group);  
    if(!messages.isEmpty()){
        mAdapter = new MessageListAdapter(getActivity().getApplicationContext(), messages);
    }
    setListAdapter(mAdapter); 
}

The adapter's getView method is never invoked after the configuration change. What else do I need to do to re-hydrate the view? Let me know if you need to see any other code.

Community
  • 1
  • 1
Matt M
  • 3,699
  • 5
  • 48
  • 76

3 Answers3

1

Since you are creating a new view then you have to redo all View's initialization that you do in the original piece of code (in onViewCreated or somewhere else). So, in order to initialize the ListView - you should do something like this:

View rootView = inflater.inflate(R.layout.activity_message_list, group);  
if(!messages.isEmpty()){
    mAdapter = new MessageListAdapter(getActivity().getApplicationContext(), messages);
}
ListView listView = (ListView) root.findViewById(R.id.<your_list_view_id>;
listView.setAdapter(mAdapter);

Just keep in mind that you also have to do all other initialization (creating references to Views and creating onClickListeners or whatever else you're doing)

Chaosit
  • 1,116
  • 7
  • 21
  • Copy paste error. I do call setListAdapter after I re-inflate the view. Still empty list. I've edited the code. – Matt M Aug 14 '15 at 13:59
  • Actually after your comment about two layouts I can say that you do not have to handle configChanges in this case - this is actually how you are supposed to handle orientation changes - through recreation of the Activity and, thus, Fragments. As for your problem - the root of it is the fact that in `onConfigurationChanged` ListFragment does not do ListView binding. According to the source code: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.0.1_r1/android/app/ListFragment.java#201 it is done in onViewCreated – Chaosit Aug 14 '15 at 14:06
  • If I don't handle the config change, I get the same layout on orientation change. For example. If I open the view on a table in portrait, i get my single pane layout. If I change the orientation after the view is created, it stays in single pane. If I open the view in land, I get my two pane layout and when I go to portrait, it stays in two pane. So it appears to me that I do have to handle this myself.....which is where I'm stuck. Make sense? – Matt M Aug 14 '15 at 14:21
  • 1
    @MattyM I was referring to removal of the `android:configChanges="orientation"` from the Activity tag - this will cause the activity to be recreated after the orientation change - just save some data crucial for the app state recreation in `onSaveInstanceState` and use it in `onCreate` of the activity. That's the default and recommended way of handling of configuration changes – Chaosit Aug 14 '15 at 15:00
  • Ok. I think I'm finally starting to understand. My app has a navigation activity. I added that line to the manifest so it wouldn't reset my selection from the drawer. So, in my Navdrawer activity, I'll store the selection in my savedInstanceState and handle it onCreate. Everything seems to be working as I would expect now. Thanks for all your help! – Matt M Aug 14 '15 at 15:35
0

There is a way to avoid app reload after device orientation changed, you just have to tell system that you'll handle screen orientation changed events on your own. Have you tried to add parameter android:configChanges="orientation" inside activity tag in Manifest.xml?

alexscmar
  • 421
  • 5
  • 11
0

With a ton of direction from Chaosit, I was able to achieve what I wanted. My app has a nav drawer activity and I swap the fragment (which is a master-detail type fragment) based on the selection. I added android:configChanges="orientation" so the fragment wouldn't revert back to the default selection I made in the onCreate method of the activity. So, I removed that line and made the adjustments to store the selection in the savedInstanceState bundle. Everything is working as I would have expected now.

Matt M
  • 3,699
  • 5
  • 48
  • 76