42 votes

Comment définir l'élément actif dans le menu déroulant de la barre d'action ?

J'essaie de résoudre le problème du redémarrage de l'activité en cas de changement d'orientation.

J'ai un ActionBar avec une liste de navigation déroulante et après chaque rotation, le premier élément de cette liste est activé. Garder fragment Le contenu n'était pas difficile, mais je ne sais pas comment définir l'élément de liste actif.

Voici la définition de ActionBar :

getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
ArrayAdapter<CharSequence> list = ArrayAdapter
    .createFromResource(this, R.array.action_list, android.R.layout.simple_dropdown_item_1line);
list.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
getActionBar().setListNavigationCallbacks(list, this);

Et voici ma solution de rechange :

@Override
public boolean onNavigationItemSelected(int itemPosition, long itemId) {
    if (!application.isRotated) {
        application.activePosition = itemPosition;
        application.activeId = itemId;
        getFragmentManager().beginTransaction()
            .replace(android.R.id.content, MyFragment.newInstance(itemPosition))
            .commit();
    } else {
        application.isRotated = false;
        this.onNavigationItemSelected(application.activePosition, application.activeId);            
    }
    return true;
}

@Override
protected void onStop() {
    super.onStop();
    application.isRotated = true;
}

Mais je ne suis pas sûr que ce soit la meilleure solution.

83voto

Roman Points 1833

Je viens de trouver cette fonction. Elle est setSelectedNavigationItem(int position) .

Définir l'élément de navigation sélectionné dans la liste ou des modes de navigation par onglets.

Exemple :

actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
actionBar.setListNavigationCallbacks(adapter, this);
actionBar.setSelectedNavigationItem(position);

1voto

David Chandler Points 853

À partir de la bibliothèque de support v7, il suffit de sauvegarder/restaurer l'état de la barre d'action :

private static final String STATE_SELECTED_NAVIGATION_ITEM = "selectedNavItem";

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
    // Restore the previously serialized current dropdown position.
    if (savedInstanceState.containsKey(STATE_SELECTED_NAVIGATION_ITEM)) {
        getSupportActionBar().setSelectedNavigationItem(
                savedInstanceState.getInt(STATE_SELECTED_NAVIGATION_ITEM));
    }
}

@Override
public void onSaveInstanceState(Bundle outState) {
    // Serialize the current dropdown position.
    outState.putInt(STATE_SELECTED_NAVIGATION_ITEM, getSupportActionBar()
            .getSelectedNavigationIndex());
}

0voto

mohitum007 Points 284

Je rencontrais également le même problème. En faisant beaucoup de recherches, j'ai trouvé la solution ici :

http://mohitum.wordpress.com/tutorials/Android/ --> sous le conseil 5.

Implémentez le OnPageChangeListener et dans le onPageSelected(int position) appelez cette méthode comme ceci :

@Override
public void onPageSelected(int position) {
  mActionBar.setSelectedNavigationItem(position);
  selectInSpinnerIfPresent(position, true);
}
private void selectInSpinnerIfPresent(int position, boolean animate) {
  try {
    ActionBar actionBarView = mActionBar;
    Class<?> actionBarViewClass = actionBarView.getClass();
    Field mTabScrollViewField = actionBarViewClass.getDeclaredField(“mTabScrollView”);
    mTabScrollViewField.setAccessible(true);
    Object mTabScrollView = mTabScrollViewField.get(actionBarView);
    if (mTabScrollView == null) {
      return;
    }
    Field mTabSpinnerField = mTabScrollView.getClass().getDeclaredField(“mTabSpinner”);
    mTabSpinnerField.setAccessible(true);
    Object mTabSpinner = mTabSpinnerField.get(mTabScrollView);
    if (mTabSpinner == null) {
      return;
    }
    Method setSelectionMethod = mTabSpinner.getClass().getSuperclass().getDeclaredMethod(“setSelection”, Integer.TYPE, Boolean.TYPE);
    setSelectionMethod.invoke(mTabSpinner, position, animate);
    Method requestLayoutMethod = mTabSpinner.getClass().getSuperclass().getDeclaredMethod(“requestLayout”);
    requestLayoutMethod.invoke(mTabSpinner);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

J'espère que cela pourra aider quelqu'un d'autre.

0voto

martyonair Points 422

Codesnippet sur Gist


@Override
public void onPageScrollStateChanged(int state) {
}

@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}

@Override
public void onPageSelected(int position) {
    actionBar.setSelectedNavigationItem(position);

    selectInSpinnerIfPresent(position, true);
}

/**
 * Hack that takes advantage of interface parity between ActionBarSherlock and the native interface to reach inside
 * the classes to manually select the appropriate tab spinner position if the overflow tab spinner is showing.
 * 
 * Related issues: https://github.com/JakeWharton/ActionBarSherlock/issues/240 and
 * https://android-review.googlesource.com/#/c/32492/
 * 
 * @author toulouse@crunchyroll.com
 */
private void selectInSpinnerIfPresent(int position, boolean animate) {
    try {
        View actionBarView = findViewById(R.id.abs__action_bar);
        if (actionBarView == null) {
            int id = getResources().getIdentifier("action_bar", "id", "android");
            actionBarView = findViewById(id);
        }

        Class<?> actionBarViewClass = actionBarView.getClass();
        Field mTabScrollViewField = actionBarViewClass.getDeclaredField("mTabScrollView");
        mTabScrollViewField.setAccessible(true);

        Object mTabScrollView = mTabScrollViewField.get(actionBarView);
        if (mTabScrollView == null) {
            return;
        }

        Field mTabSpinnerField = mTabScrollView.getClass().getDeclaredField("mTabSpinner");
        mTabSpinnerField.setAccessible(true);

        Object mTabSpinner = mTabSpinnerField.get(mTabScrollView);
        if (mTabSpinner == null) {
            return;
        }

        Method setSelectionMethod = mTabSpinner.getClass().getSuperclass().getDeclaredMethod("setSelection", Integer.TYPE, Boolean.TYPE);
        setSelectionMethod.invoke(mTabSpinner, position, animate);

        Method requestLayoutMethod = mTabSpinner.getClass().getSuperclass().getDeclaredMethod("requestLayout");
        requestLayoutMethod.invoke(mTabSpinner);
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (NoSuchFieldException e) {
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }
}

ce hack autour du Bug officiel d'Android a fonctionné pour moi, le codesnippet ci-dessus n'a pas fonctionné :/

0voto

Kyle Jahnke Points 177

Cette implémentation fonctionne pour moi (une version modifiée de la réponse de @mohitum007) :

public static void selectInSpinnerIfPresent(Object inActionBar,
        int position, boolean animate) {
    // get the ActionBar class
    Class<?> actionBarClass = inActionBar.getClass();

    // if it is a Jelly Bean implementation (ActionBarImplJB), get the super
    // class (ActionBarImplICS)
    if ("android.support.v7.app.ActionBarImplJB".equals(actionBarClass
            .getName())) {
        actionBarClass = actionBarClass.getSuperclass();
    }
    try {
        // try to get the mActionBar field, because the current ActionBar is
        // probably just a wrapper Class
        // if this fails, no worries, this will be an instance of the native
        // ActionBar class or from the ActionBarImplBase class
        final Field actionBarField = actionBarClass
                .getDeclaredField("mActionBar");
        actionBarField.setAccessible(true);
        inActionBar = actionBarField.get(inActionBar);
        actionBarClass = inActionBar.getClass();
    } catch (IllegalAccessException e) {
    } catch (IllegalArgumentException e) {
    } catch (NoSuchFieldException e) {
    }
    try {
        Field mTabScrollViewField = actionBarClass
                .getDeclaredField("mTabScrollView");
        mTabScrollViewField.setAccessible(true);
        Object mTabScrollView = mTabScrollViewField.get(inActionBar);
        if (mTabScrollView == null) {
            return;
        }
        Field mTabSpinnerField = mTabScrollView.getClass()
                .getDeclaredField("mTabSpinner");
        mTabSpinnerField.setAccessible(true);
        Object mTabSpinner = mTabSpinnerField.get(mTabScrollView);
        if (mTabSpinner == null) {
            return;
        }
        Method setSelectionMethod = mTabSpinner
                .getClass()
                .getSuperclass()
                .getDeclaredMethod("setSelection", Integer.TYPE,
                        Boolean.TYPE);
        setSelectionMethod.invoke(mTabSpinner, position, animate);
        Method requestLayoutMethod = mTabSpinner.getClass().getSuperclass()
                .getDeclaredMethod("requestLayout");
        requestLayoutMethod.invoke(mTabSpinner);
    } catch (NoSuchMethodException | InvocationTargetException
            | IllegalAccessException | IllegalArgumentException | NoSuchFieldException e) {
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X