Problems Switching ListView ChoiceMode While Rotating Screen

I am trying to create a shared panel based on the sample code presented at the end of the Android documentation on fragments, mainly LinearLayout containing two fragments (all details can be found in the link above):

  • TitlesFragmentto display a list of names
  • DetailsFragmentto display information about the currently selected title

My problem is that the following unexpected behavior occurs:

  • I launch the application in the Landscape orientation : the list of headers is displayed on the left, and the data of the currently selected header (the first one at the beginning) is displayed on the right.
  • I select the X element from the list of titles: the title becomes highlighted, since the ListView matters CHOICE_MODE_SINGLE, and its elements implement the interface Checkable.
  • I switch to portrait orientation (by rotating the device or emulator): as expected, only the list of titles is displayed, and no element is selected in this configuration, since the ListView is recreated and the default value is set CHOICE_MODE_NONE.
  • I select the Y element from the list of titles: as expected, an action is displayed showing only the one DetailsFragmentthat matches the selected selection.
  • (, ): DetailsFragment Y ( ), TitlesFragment - X ( , ).

, , , , TitlesFragment, , X, Y.

, ListView ( 'onActivityCreated'), ( 'showDetails'):

public static class TitlesFragment extends ListFragment {
boolean mDualPane;
int mCurCheckPosition = 0;

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    // Populate list with our static array of titles.
    setListAdapter(new ArrayAdapter<String>(getActivity(),
            android.R.layout.simple_list_item_activated_1, Shakespeare.TITLES));

    // Check to see if we have a frame in which to embed the details
    // fragment directly in the containing UI.
    View detailsFrame = getActivity().findViewById(R.id.details);
    mDualPane = detailsFrame != null && detailsFrame.getVisibility() == View.VISIBLE;

    if (savedInstanceState != null) {
        // Restore last state for checked position.
        mCurCheckPosition = savedInstanceState.getInt("curChoice", 0);
    }

    if (mDualPane) {
        // In dual-pane mode, the list view highlights the selected item.
        getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
        // Make sure our UI is in the correct state.
        showDetails(mCurCheckPosition);
    }
}

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putInt("curChoice", mCurCheckPosition);
}

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

/**
 * Helper function to show the details of a selected item, either by
 * displaying a fragment in-place in the current UI, or starting a
 * whole new activity in which it is displayed.
 */
void showDetails(int index) {
    mCurCheckPosition = index;

    if (mDualPane) {
        // We can display everything in-place with fragments, so update
        // the list to highlight the selected item and show the data.
        getListView().setItemChecked(index, true);

        // Check what fragment is currently shown, replace if needed.
        DetailsFragment details = (DetailsFragment)
                getFragmentManager().findFragmentById(R.id.details);
        if (details == null || details.getShownIndex() != index) {
            // Make new fragment to show this selection.
            details = DetailsFragment.newInstance(index);

            // Execute a transaction, replacing any existing fragment
            // with this one inside the frame.
            FragmentTransaction ft = getFragmentManager().beginTransaction();
            ft.replace(R.id.details, details);
            ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
            ft.commit();
        }

    } else {
        // Otherwise we need to launch a new activity to display
        // the dialog fragment with selected text.
        Intent intent = new Intent();
        intent.setClass(getActivity(), DetailsActivity.class);
        intent.putExtra("index", index);
        startActivity(intent);
    }
}

- , ? .

+5
4

Android v4, !

, , CHOICE_MODE_SINGLE :

getListView().setItemChecked(mCurCheckPosition, true); onResume() TitlesFragment. ... !

+2

, outState , super.onSaveInstanceState?

@Override
public void onSaveInstanceState(Bundle outState) {
    outState.putInt("curChoice", mCurCheckPosition);
    super.onSaveInstanceState(outState);
}
0

, setItemChecked onStart:

@Override
public void onStart() {
    super.onStart();
    if (mDualPane) {
        getListView().setItemChecked(mCurCheckPosition, true);
    }
}

, LearningNerd, onResume()

0

If you put android:configChanges="orientation"in your activity tag in the manifest file, your application will ignore the rotation, but still display the corresponding layouts.

-2
source

All Articles