How to set active item in the Action Bar drop-down navigation?

前端 未结 5 1111
清歌不尽
清歌不尽 2020-12-13 00:23

I\'m trying to fix the issue with restarting activity on orientation changes.

I have an ActionBar with drop-down list navigation and after every rotatio

相关标签:
5条回答
  • 2020-12-13 00:42

    I was also experiencing the same issue. Making a lot of research I found the solution here:

    http://mohitum.wordpress.com/tutorials/android/ -->under Tip 5.

    Implement OnPageChangeListener and in the onPageSelected(int position) call this method like this:

    @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();
        }
      }
    

    I hope this may help someone else too.

    0 讨论(0)
  • 2020-12-13 00:43

    This implementation works for me (a modified version of @mohitum007's response):

    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) {
        }
    }
    
    0 讨论(0)
  • 2020-12-13 00:45

    Codesnippet on 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();
        }
    }
    

    this hack around the official Android Bug did it for me, the codesnippet above did not :/

    0 讨论(0)
  • 2020-12-13 00:46

    As of support library v7, you just need to save / restore the state of the ActionBar:

    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());
    }
    
    0 讨论(0)
  • 2020-12-13 00:59

    I just found that function. It is setSelectedNavigationItem(int position).

    Set the selected navigation item in list or tabbed navigation modes.

    Example:

    actionBar = getActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
    actionBar.setListNavigationCallbacks(adapter, this);
    actionBar.setSelectedNavigationItem(position);
    
    0 讨论(0)
提交回复
热议问题