Переключение между Android навигация ящик изображение и курсор при использовании фрагментов

При использовании навигации на Андроид разработчики рекомендуют в ActionBar "и только те экраны, которые представлены в навигационной ящик, должны иметь меню навигации изображения" и что "все остальные экраны имеют традиционное до карата.&и"

Смотрите здесь для деталей: http://youtu.be/F5COhlbpIbY

Я'м, используя одно действие для управления несколькими уровнями фрагментов и может получить изображение навигации ящика для отображения и функции на всех уровнях.

При создании Нижнего фрагмента уровне я могу назвать ActionBarDrawerToggle setDrawerIndicatorEnabled(ложные), чтобы скрыть изображение навигации ящик и до каре отображается

LowerLevelFragment lowFrag = new LowerLevelFragment();

//disable the toggle menu and show up carat
theDrawerToggle.setDrawerIndicatorEnabled(false);
getSupportFragmentManager().beginTransaction().replace(R.id.frag_layout, 
lowFrag, "lowerFrag").addToBackStack(null).commit();

Проблема, которую я'м, когда я перейти обратно на верхний уровень фрагментов до карат-прежнему показывает вместо оригинального навигационного изображения ящика. Любые предложения о том, чтобы "обновить" в ActionBar на верхней фрагменты уровне, чтобы повторно отобразить изображение навигации ящик?

<ч> <Н2>решение</Н2> Тома'предложением работал для меня. Вот что я сделал:

<Н3>в MainActivity</Н3> Эту деятельность контролирует все фрагменты в приложении.

При подготовке новых фрагментов заменить другим, я setDrawerIndicatorEnabled в DrawerToggle (нет), как это:

LowerLevelFragment lowFrag = new LowerLevelFragment();

//disable the toggle menu and show up carat
theDrawerToggle.setDrawerIndicatorEnabled(false);
getSupportFragmentManager().beginTransaction().replace(R.id.frag_layout,   
lowFrag).addToBackStack(null).commit();

Далее, в переопределение onBackPressed, я вернулась выше, установив DrawerToggle к setDrawerIndicatorEnabled(правда)` такой:

@Override
public void onBackPressed() {
    super.onBackPressed();
    // turn on the Navigation Drawer image; 
    // this is called in the LowerLevelFragments
    setDrawerIndicatorEnabled(true)
}

<ч>

<Н3>в LowerLevelFragments</Н3> В осколки я изменил метод и будет onoptionsitemselected такой:

В методе onCreateдобавленоsetHasOptionsMenu(правда), чтобы включить настройки меню опции. Также Сеть setDisplayHomeAsUpEnabled(true), то для включения <б><</б> в ActionBar:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // needed to indicate that the fragment would 
    // like to add items to the Options Menu        
    setHasOptionsMenu(true);    
    // update the actionbar to show the up carat/affordance 
    getActivity().getActionBar().setDisplayHomeAsUpEnabled(true);
}

Потом будет onoptionsitemselectedвсякий раз, когда <б><</б> нажатии она вызываетonBackPressed()` от действия для перемещения на один уровень вверх в иерархии и отображение меню навигации изображения:

@Override
public boolean onOptionsItemSelected(MenuItem item) {   
    // Get item selected and deal with it
    switch (item.getItemId()) {
        case android.R.id.home:
            //called when the up affordance/carat in actionbar is pressed
            getActivity().onBackPressed();
            return true;
        … 
    }
Комментарии к вопросу (7)

Это's легко, как 1-2-3.

Если вы хотите достичь:

  1. ящик индикатора - при отсутствии фрагментов в задней стеке или ящик открыт

  2. Стрела - когда некоторые фрагменты в резервную стопку

private FragmentManager.OnBackStackChangedListener
        mOnBackStackChangedListener = new FragmentManager.OnBackStackChangedListener() {
    @Override
    public void onBackStackChanged() {
        syncActionBarArrowState();
    }
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    getSupportActionBar().setDisplayShowHomeEnabled(true);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    mDrawerToggle = new ActionBarDrawerToggle(
            this,             
            mDrawerLayout,  
            R.drawable.ic_navigation_drawer, 
            0, 
            0  
    ) {

        public void onDrawerClosed(View view) {
            syncActionBarArrowState();
        }

        public void onDrawerOpened(View drawerView) {
            mDrawerToggle.setDrawerIndicatorEnabled(true);
        }
    };

    mDrawerLayout.setDrawerListener(mDrawerToggle);
    getSupportFragmentManager().addOnBackStackChangedListener(mOnBackStackChangedListener);
}

@Override
protected void onDestroy() {
    getSupportFragmentManager().removeOnBackStackChangedListener(mOnBackStackChangedListener);
    super.onDestroy();
}

private void syncActionBarArrowState() {
    int backStackEntryCount = 
        getSupportFragmentManager().getBackStackEntryCount();
    mDrawerToggle.setDrawerIndicatorEnabled(backStackEntryCount == 0);
}
  1. оба показателя действовать согласно их форме
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (mDrawerToggle.isDrawerIndicatorEnabled() && 
        mDrawerToggle.onOptionsItemSelected(item)) {
        return true;
    } else if (item.getItemId() == android.R.id.home && 
               getSupportFragmentManager().popBackStackImmediate()) {
        return true;
    } else {
        return super.onOptionsItemSelected(item);
    }
}

П. С. см. [создаем панель навигации на Android] разработчики1 по другим советы по поводу 3-индикаторные линии поведения.

Комментарии (16)
Решение

Вы написали, что для реализации нижнего уровня фрагментов, вы заменяете существующий фрагмент, в отличие от исполнителей более низкого уровня фрагмент в новый вид деятельности.

Я думаю, что тогда вам придется реализующими функции вручную: когда пользователь нажал назад у вас есть код, который берет стек (например, в деятельность::переопределить onBackPressed). Поэтому, где бы вы сделаете это, вы можете изменить setDrawerIndicatorEnabled.

Комментарии (3)

Я'вэ используется следующая вещь:

getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
            @Override
            public void onBackStackChanged() {
                if(getSupportFragmentManager().getBackStackEntryCount() > 0){
                    mDrawerToggle.setDrawerIndicatorEnabled(false);
                    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
                }
                else {
                    getSupportActionBar().setDisplayHomeAsUpEnabled(false);
                    mDrawerToggle.setDrawerIndicatorEnabled(true);
                }
            }
        });
Комментарии (1)

Если кнопка на панели действий не't работа, Дон'т забудьте добавить слушателя :

// Navigation back icon listener
mDrawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            onBackPressed();
        }
});

Я'ве получил некоторые проблемы реализации ящике навигации с кнопку Home, все работало, за исключением бутон действий.

Комментарии (0)

Попробовать регулировать подбор домашнего пункта в класс MainActivity в зависимости от состояния DrawerToggle. Таким образом, вы Дон'т иметь, чтобы добавить тот же код для каждого фрагмента.

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Only handle with DrawerToggle if the drawer indicator is enabled.
    if (mDrawerToggle.isDrawerIndicatorEnabled() &&
            mDrawerToggle.onOptionsItemSelected(item)) {
        return true;
    }
    // Handle action buttons
    switch (item.getItemId()) {
        // Handle home button in non-drawer mode
        case android.R.id.home:
            onBackPressed();
            return true;

        default:
            return super.onOptionsItemSelected(item);
    }
}
Комментарии (3)

ПОСЛЕДУЮЩИЕ

Решение дано @dzeikei аккуратно, но он может быть продлен, при использовании фрагментов, автоматически отбрасывая показатель ящик, когда backstack пуст.

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Only handle with DrawerToggle if the drawer indicator is enabled.
    if (mDrawerToggle.isDrawerIndicatorEnabled() &&
            mDrawerToggle.onOptionsItemSelected(item)) {
        return true;
    }
    // Handle action buttons
    switch (item.getItemId()) {
        // Handle home button in non-drawer mode
        case android.R.id.home:
            // Use getSupportFragmentManager() to support older devices
            FragmentManager fragmentManager = getFragmentManager();
            fragmentManager.popBackStack();
            // Make sure transactions are finished before reading backstack count
            fragmentManager.executePendingTransactions();
            if (fragmentManager.getBackStackEntryCount() < 1){
                mDrawerToggle.setDrawerIndicatorEnabled(true);  
            }
            return true;

        default:
            return super.onOptionsItemSelected(item);
    }
}

Редактировать

На вопрос @JJD.

Фрагменты проводятся/управляемые в действии. Приведенный выше код пишется один раз в этой деятельности, но ручка только до каре для будет onoptionsitemselected.

В одном из моих приложений, мне нужно, чтобы справиться с поведением до каре, когда кнопки "назад" была нажата. Это может быть ручка, переопределив onBackPressed.

@Override
public void onBackPressed() {
    // Use getSupportFragmentManager() to support older devices
    FragmentManager fragmentManager = getFragmentManager();
    fragmentManager.executePendingTransactions();
    if (fragmentManager.getBackStackEntryCount() < 1){
        super.onBackPressed();
    } else {
        fragmentManager.executePendingTransactions();
        fragmentManager.popBackStack();
        fragmentManager.executePendingTransactions();
        if (fragmentManager.getBackStackEntryCount() < 1){
            mDrawerToggle.setDrawerIndicatorEnabled(true);
        }
    }
};

Обратите внимание на дублирование кода между будет onoptionsitemselected и onBackPressed, который можно избежать путем создания метода и вызов этого метода в обоих местах.

Также обратите внимание, я добавляю еще два раза executePendingTransactions что в моем случае было необходимо, иначе у меня иногда странное поведение до каре.

Комментарии (4)

Этот ответ работает, но есть небольшая проблема с ним. В getSupportActionBar().setDisplayHomeAsUpEnabled(ложные) не вызывается явно, и это вызывает значок лотка, чтобы быть скрыты, даже если не было никаких предметов в backstack поэтому изменениеsetActionBarArrowDependingOnFragmentsbackstack (метод)` работал для меня.

private void setActionBarArrowDependingOnFragmentsBackStack() {
        int backStackEntryCount = getSupportFragmentManager()
                .getBackStackEntryCount();
        // If there are no items in the back stack
        if (backStackEntryCount == 0) {
            // Please make sure that UP CARAT is Hidden otherwise Drawer icon
            // wont display
            getSupportActionBar().setDisplayHomeAsUpEnabled(false);
            // Display the Drawer Icon
            mDrawerToggle.setDrawerIndicatorEnabled(true);
        } else {
            // Show the Up carat
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
            // Hide the Drawer Icon
            mDrawerToggle.setDrawerIndicatorEnabled(false);
        }

    }
Комментарии (1)

Я создал интерфейс для таких действия, чтобы обновить представление состояния меню гамбургер. Для верхней фрагменты уровень я поставил тумблер true и фрагментов, по которым я хочу, чтобы отобразить вверх < стрелка я поставил тумблер на "false".

public class SomeFragment extends Fragment {

    public interface OnFragmentInteractionListener {
        public void showDrawerToggle(boolean showDrawerToggle);
    }

    private OnFragmentInteractionListener mListener;

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            this.mListener = (OnFragmentInteractionListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        mListener.showDrawerToggle(false);
    }
}

Затем в моей деятельности ...

public class MainActivity extends Activity implements SomeFragment.OnFragmentInteractionListener {

    private ActionBarDrawerToggle mDrawerToggle;

    public void showDrawerToggle(boolean showDrawerIndicator) {
        mDrawerToggle.setDrawerIndicatorEnabled(showDrawerIndicator);
    }

}
Комментарии (0)

Если вы взгляните на Gmail приложения и приходят сюда для поиска Каррет/допустимого значок..

Я бы попросил вас сделать это, ни один из вышеперечисленных ответ был ясен. я был в состоянии изменить принятый ответ.

  • NavigationDrawer --> элемент ListView содержит subfragments.

  • subfragments будут перечислены, как это

  • firstFragment == позиция 0 ---> это будет иметь subfragments --> фрагмент

  • secondFragment

  • thirdFragment и так далее....

В firstFragment у вас есть другой фрагмент.

Называют это по DrawerActivity

getFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
        @Override
        public void onBackStackChanged() {
            if (getFragmentManager().getBackStackEntryCount() > 0) {
                mDrawerToggle.setDrawerIndicatorEnabled(false);
            } else {
                mDrawerToggle.setDrawerIndicatorEnabled(true);
            }
        }
    });

и в фрагмент

    setHasOptionsMenu(true);    

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Get item selected and deal with it
    switch (item.getItemId()) {
        case android.R.id.home:
            //called when the up affordance/carat in actionbar is pressed
            activity.onBackPressed();
            return true;
    }
    return false;
}

На OnBackPressed метод активности ящика комплект ящика переключить в значение true, чтобы снова включить значок списка навигации.

Спасибо, Pusp

Комментарии (0)

Логика понятна. Показать кнопку назад, если задняя стека фрагмента ясна. Показать материал гамбургер-задняя анимации, если стек фрагмент не понятно.

getSupportFragmentManager().addOnBackStackChangedListener(
    new FragmentManager.OnBackStackChangedListener() {
        @Override
        public void onBackStackChanged() {
            syncActionBarArrowState();
        }
    }
);

private void syncActionBarArrowState() {
    int backStackEntryCount = getSupportFragmentManager().getBackStackEntryCount();
    mNavigationDrawerFragment.setDrawerIndicatorEnabled(backStackEntryCount == 0);
}

//add these in Your NavigationDrawer fragment class

public void setDrawerIndicatorEnabled(boolean flag){
    ActionBar actionBar = getActionBar();
    if (!flag) {
        mDrawerToggle.setDrawerIndicatorEnabled(false);
        actionBar.setDisplayHomeAsUpEnabled(true);
        mDrawerToggle.setHomeAsUpIndicator(getColoredArrow());
    } else {
        mDrawerToggle.setDrawerIndicatorEnabled(true);
    }
    mDrawerToggle.syncState();
    getActivity().supportInvalidateOptionsMenu();
}

//download back button from this(https://www.google.com/design/icons/) website and add to your project

private Drawable getColoredArrow() {
    Drawable arrowDrawable = ContextCompat.getDrawable(getActivity(), R.drawable.ic_arrow_back_black_24dp);
    Drawable wrapped = DrawableCompat.wrap(arrowDrawable);

    if (arrowDrawable != null && wrapped != null) {
        // This should avoid tinting all the arrows
        arrowDrawable.mutate();
        DrawableCompat.setTint(wrapped, Color.GRAY);
    }
    return wrapped;
}
Комментарии (0)

Вы можете посмотреть на этом маленьком примере! https://github.com/oskarko/NavDrawerExample

Комментарии (0)

ИМО, используя onNavigateUp() (как показано здесь) в riwnodennyk's или Тома'ный раствор чище и, кажется, работает лучше. Просто замените код будет onoptionsitemselected с этим:

@Override
public boolean onSupportNavigateUp() {
    if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
        // handle up navigation
        return true;
    } else {
        return super.onSupportNavigateUp();
    }
}
Комментарии (0)