Стрелката нагоре/назад на лентата с инструменти на AppCompat v7 не работи

Имам два фрагмента в дейност. Когато се показва фрагмент A, искам иконата на бургер в чекмеджето за навигация да се показва и чекмеджето за навигация да работи. Когато се показва фрагмент B, искам да се покаже стрелката за назад и когато се щракне върху нея, да се направи навигация нагоре. Изглежда обаче не мога да накарам новата лента с инструменти AppCompat v7 изобщо да показва стрелката нагоре в моя ActionBarActivity, освен ако чекмеджето за навигация не е отворено.

В моята дейност, за моя метод onCreate() имам...

toolbar = (Toolbar) findViewById(R.id.toolbar);
if (toolbar != null) {
    setSupportActionBar(toolbar);
}
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, toolbar, R.string.drawer_open, R.string.drawer_close);
mDrawerLayout.setDrawerListener(mDrawerToggle);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);

И тогава извиквам mDrawerToggle.syncState(); в моя onPostCreate()

Опитах се да потърся как програмно да задействам иконата на лентата с инструменти към стрелката назад, но нищо не проработи. От това, което събрах, се обаждам

getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);

от моя фрагмент трябва да промени иконата, но това не е така. Това може да е глупав въпрос, но какво правя грешно?


person Leonardo Casale    schedule 10.11.2014    source източник


Отговори (4)


От това, което видях в изходния код на v7 ActionBarDrawerToggle, можете да анимирате иконата в различни състояния, без да се отваря чекмеджето.

 private enum ActionDrawableState{
        BURGER, ARROW
    }
    private static void toggleActionBarIcon(ActionDrawableState state, final ActionBarDrawerToggle toggle, boolean animate){
        if(animate) {
            float start = state == ActionDrawableState.BURGER ? 0f : 1.0f;
            float end = Math.abs(start - 1);
            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                ValueAnimator offsetAnimator = ValueAnimator.ofFloat(start, end);
                offsetAnimator.setDuration(300);
                offsetAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
                offsetAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        float offset = (Float) animation.getAnimatedValue();
                        toggle.onDrawerSlide(null, offset);
                    }
                });
               offsetAnimator.start();
            }else{
                //do the same with nine-old-androids lib :)
            }
        }else{
            if(state == ActionDrawableState.BURGER){
                toggle.onDrawerClosed(null);
            }else{
                toggle.onDrawerOpened(null);
            }
        }
    }

Преобразуването между Burger и Arrow зависи от стойности между 0f и 1.0f, основно това са стойности, които чекмеджето предава на ActionBarDrawerToggle.

Използвах ValueAnimator за анимиране на стойности в този диапазон, т.е. имитиране на превключването на чекмеджетата.

null аргументите са безопасни, защото ActionBarDrawerToggle изобщо не се интересува от изгледите на чекмеджетата. Уверете се, че сте разгледали новите интерполатори, за да направите анимацията изцяло според указанията за материален дизайн:

fast_out_linear_in  
fast_out_slow_in

Друг подход е достъп до mSlider частно поле на ActionBarDrawer чрез отражение и извикване на метод setPosition(float position) за превключване между Burger и Arrow. mSlider е от тип (разширява) DrawerArrowDrawable.

Лично аз винаги се опитвам да избягвам размисъл, стига да няма друг начин да си свършиш мръсната работа.

person Nikola Despotoski    schedule 10.11.2014
comment
Точно това търсех. Благодаря! - person Leonardo Casale; 16.11.2014

Тъй като библиотеката за поддръжка е актуализирана до 23.0.0, има по-добър начин за възпроизвеждане на анимация със стрелка на чекмедже. Така че ще подобря отговора на @Nikola. Ето кода:

public static void playDrawerToggleAnim(final DrawerArrowDrawable d) {
    float start = d.getProgress();
    float end = Math.abs(start - 1);
    ValueAnimator offsetAnimator = ValueAnimator.ofFloat(start, end);
    offsetAnimator.setDuration(300);
    offsetAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
    offsetAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            float offset = (Float) animation.getAnimatedValue();
            d.setProgress(offset);
        }
    });
    offsetAnimator.start();
}

И го извикайте, когато пожелаете чрез:

playDrawerToggleAnim((DrawerArrowDrawable) toolbar.getNavigationIcon());
person ywwynm    schedule 29.08.2015

getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
        @Override
        public void onBackStackChanged() {
            int stackHeight = getSupportFragmentManager().getBackStackEntryCount();
            if (stackHeight > 0) { // if we have something on the stack (doesn't include the current shown fragment)
                getSupportActionBar().setHomeButtonEnabled(true);
                getSupportActionBar().setDisplayHomeAsUpEnabled(true);
            } else {
                getSupportActionBar().setDisplayHomeAsUpEnabled(false);
                getSupportActionBar().setHomeButtonEnabled(false);
            }
        }

    });

След ...

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            getSupportFragmentManager().popBackStack();
            return true;
     ....
 }
person vrbsm    schedule 03.06.2015

В моя случай иконата е анимирана: използвах ActionBarDrawerToggle v7.

Основна дейност:

    Toolbar toolbar = (Toolbar) findViewById(R.id.tool1);

    setSupportActionBar(toolbar);
    toolbar.setTitle("ToolBar Demo");
    toolbar.setLogo(R.drawable.ic_launcher);

    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);

    mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, toolbar,
            R.string.open_navigation_drawer,
            R.string.close_navigation_drawer) {

        @Override
        public void onDrawerSlide(View drawerView, float slideOffset) {
            // TODO Auto-generated method stub
            super.onDrawerSlide(drawerView, slideOffset);
        }

        /** Called when a drawer has settled in a completely closed state. */
        @Override
        public void onDrawerClosed(View view) {
            super.onDrawerClosed(view);
            getSupportActionBar().setTitle("hello");
        }

        /** Called when a drawer has settled in a completely open state. */
        @Override
        public void onDrawerOpened(View drawerView) {
            super.onDrawerOpened(drawerView);
            getSupportActionBar().setTitle("hi");
        }
    };
    mDrawerLayout.setDrawerListener(mDrawerToggle);



}

@Override
public boolean onOptionsItemSelected(MenuItem item) { // <---- added
    if (mDrawerToggle.onOptionsItemSelected(item)) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

@Override
protected void onPostCreate(Bundle savedInstanceState) { // <---- added
    super.onPostCreate(savedInstanceState);
    mDrawerToggle.syncState(); // important statetment for drawer to
                                // identify
                                // its state
}

@Override
public void onConfigurationChanged(Configuration newConfig) { // <---- added
    super.onConfigurationChanged(newConfig);
    mDrawerToggle.onConfigurationChanged(newConfig);
}

@Override
public void onBackPressed() {
    if (mDrawerLayout.isDrawerOpen(Gravity.START | Gravity.LEFT)) { // <----
                                                                    // added
        mDrawerLayout.closeDrawers();
        return;
    }
    super.onBackPressed();
}
person kunal.c    schedule 11.11.2014