это - выдвигающееся меню android




Переключение между изображениями Android Navigation Drawer и Up caret при использовании фрагментов (8)

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

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

Подробнее см. Здесь: http://youtu.be/F5COhlbpIbY

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

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

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 на фрагментах верхнего уровня, чтобы повторно отобразить изображение навигационного ящика?

Решение

Предложение Тома работало для меня. Вот что я сделал:

Основная деятельность

Это действие контролирует все фрагменты в приложении.

При создании новых фрагментов для замены других я устанавливаю DrawerToggle setDrawerIndicatorEnabled(false) следующим образом:

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(true) следующим образом:

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

В LowerLevelFragments

Во фрагментах я изменил onCreate и onOptionsItemSelected следующим образом:

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

@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 всякий раз, когда 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;
        … 
    }

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

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


Если вы посмотрите на приложение GMAIL и придете сюда, чтобы найти значок carret / vacance.

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

  • NavigationDrawer -> Listview содержит подфрагменты.

  • субфрагменты будут перечислены следующим образом:

  • firstFragment == position 0 ---> у этого будут субфрагменты -> фрагмент

  • secondFragment
  • третий фрагмент и т. д ....

В 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 Drawer установите для переключателя ящика значение true, чтобы снова включить значок списка навигации.

Спасибо, Pusp


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

@Override
public boolean onSupportNavigateUp() {
    if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
        // handle up navigation
        return true;
    } else {
        return super.onSupportNavigateUp();
    }
}

Попробуйте обработать выбор элемента Home в 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);
    }
}

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

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

1) Индикатор ящика - при отсутствии фрагментов в Back Stack или ящике

2) Стрелка - когда некоторые фрагменты находятся в Back Stack

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

3) Оба индикатора действуют в соответствии с их формой

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

PS См. Раздел Создание навигационного ящика на Android Developers в других советах о поведении индикаторов из 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);
                }
            }
        });

Я создал интерфейс для хостинговой деятельности, чтобы обновить состояние представления меню гамбургера. Для фрагментов верхнего уровня я устанавливаю toggle в true и для фрагментов, для которых я хочу отобразить up <стрелка, я установил toggle в 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);
    }

}




navigation-drawer