0

I'm building a ListFragment. In portrait it needs two headers, but in landscape I need these headers on the left side with the ListView on the right side. The xml handles the different layouts and the java handles properly filling/updating them.

That all works as advertised except that on orientation change the headers are not retained with the list. The listView even retains the scroll but is shift by the removal of the headers.

It might be better to nest a fragment but the listview wouldn't hold the framelayout so that's a moot point.

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setRetainInstance(true);

    loadFeeds();
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.fragment_profile, container, false);

    return v;
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    setupList(savedInstanceState);
    setupOrienation();

    super.onActivityCreated(savedInstanceState);
}

private void setupList(Bundle savedInstanceState) {
    if(getListAdapter() == null) {
        listProfileButtons = (View)getLayoutInflater(savedInstanceState).inflate(R.layout.view_profile_buttons, null);
        listProfile = (View)getLayoutInflater(savedInstanceState).inflate(R.layout.view_profile_header, null);

        getListView().addHeaderView(listProfile);
        getListView().addHeaderView(listProfileButtons);
    } 
}

private void setupOrienation(){
    if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
        listProfile.setVisibility(View.GONE);
        listProfileButtons.setVisibility(View.GONE);
        setupProfile(getView());
        setupButtons(getView());
        getListView().setOnScrollListener(new OnScrollListener() {

            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            }
        });
    } else {
        listProfile.setVisibility(View.VISIBLE);
        listProfileButtons.setVisibility(View.VISIBLE);
        //setupProfile(getListView());
        //setupButtons(getListView());
        setupButtons(getView().findViewById(R.id.include_profile_buttons));

        getListView().setOnScrollListener(new OnScrollListener() {

            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                if(firstVisibleItem > 0) {
                    getView().findViewById(R.id.include_profile_buttons).setVisibility(View.VISIBLE);
                } else {
                    getView().findViewById(R.id.include_profile_buttons).setVisibility(View.GONE);
                }

            }
        });

    }
}

private void setupProfile(View parent) {
    Bundle userBundle = getArguments();

    TextView name = (TextView)parent.findViewById(R.id.text_view_profile_name);
    TextView screenName = (TextView)parent.findViewById(R.id.text_view_profile_at_user);
    ImageView image = (ImageView)parent.findViewById(R.id.image_view_profile_picture);

    name.setText(userBundle.getString(User.USER_NAME));
    screenName.setText("@" + userBundle.get(User.SCREEN_NAME));
    ImageCacheManager.getInstance(getActivity()).bindDrawable(userBundle.getString(User.PROFILE_IMAGE), image);

}

private void setupButtons(View v) {
    Bundle userBundle = getArguments();

    Button buttonTweets = (Button)v.findViewById(R.id.button_number);
    Button buttonFollowing = (Button)v.findViewById(R.id.button_follow);
    Button buttonFollowers = (Button)v.findViewById(R.id.button_friends);

    buttonTweets.setText(getResources().getString(R.string.profile_number, userBundle.getInt(User.NUMBER)));
    buttonFollowing.setText(getResources().getString(R.string.profile_number_follow, userBundle.getInt(User.NUMBER_OF_FOLLOW)));
    buttonFollowers.setText(getResources().getString(R.string.profile_number_friends, userBundle.getInt(User.NUMBER_OF_FRIENDS)));

    buttonTweets.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            switchListAdapter(adapter);
        }
    });

    buttonFollowing.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            switchListAdapter(followAdapter);
        }
    });

    buttonFollowers.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            switchListAdapter(friendsAdapter);
        }
    });
}

Commented code is done so to stop null pointer exceptions after the headers are lost.

4

1 回答 1

2

So on rotation all views get destroyed, which means the headers. I believe that when you setRatainInstance(true) it should handle the headers in a ListFragment headers but does not. To use Headers with ListFragment that uses retainInstance you have to:

@Override
public void onDestroyView() {
    setListAdapter(null);
    super.onDestroyView();
}

Then I only add headers in the orientation that I need them, which is nice. The negative part about it is the scroll isn't retained and I have to figure out which adapter should be in. Those are only a couple methods though which isn't too bad.

于 2013-03-19T21:18:19.327 回答