При использовании навигации на Андроид разработчики рекомендуют в ActionBar "и только те экраны, которые представлены в навигационной ящик, должны иметь меню навигации изображения" и что "все остальные экраны имеют традиционное до карата.&и"
Смотрите здесь для деталей:
Я'м, используя одно действие для управления несколькими уровнями фрагментов и может получить изображение навигации ящика для отображения и функции на всех уровнях.
При создании Нижнего фрагмента уровне я могу назвать 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;
…
}
Это's легко, как 1-2-3.
Если вы хотите достичь:
ящик индикатора - при отсутствии фрагментов в задней стеке или ящик открыт
Стрела - когда некоторые фрагменты в резервную стопку
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);
}
@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-индикаторные линии поведения.
Вы написали, что для реализации нижнего уровня фрагментов, вы заменяете существующий фрагмент, в отличие от исполнителей более низкого уровня фрагмент в новый вид деятельности.
Я думаю, что тогда вам придется реализующими функции вручную: когда пользователь нажал назад у вас есть код, который берет стек (например, в деятельность::переопределить onBackPressed
). Поэтому, где бы вы сделаете это, вы можете изменить setDrawerIndicatorEnabled
.
Я'вэ используется следующая вещь:
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);
}
}
});
Если кнопка на панели действий не't работа, Дон'т забудьте добавить слушателя :
// Navigation back icon listener
mDrawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onBackPressed();
}
});
Я'ве получил некоторые проблемы реализации ящике навигации с кнопку 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);
}
}
ПОСЛЕДУЮЩИЕ
Решение дано @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
что в моем случае было необходимо, иначе у меня иногда странное поведение до каре.
Этот ответ работает, но есть небольшая проблема с ним.
В 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);
}
}
Я создал интерфейс для таких действия, чтобы обновить представление состояния меню гамбургер. Для верхней фрагменты уровень я поставил тумблер 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);
}
}
Если вы взгляните на Gmail приложения и приходят сюда для поиска Каррет/допустимого значок..
Я бы попросил вас сделать это, ни один из вышеперечисленных ответ был ясен. я был в состоянии изменить принятый ответ.
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
Логика понятна. Показать кнопку назад, если задняя стека фрагмента ясна. Показать материал гамбургер-задняя анимации, если стек фрагмент не понятно.
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;
}
ИМО, используя onNavigateUp() (как показано здесь) в riwnodennyk's или Тома'ный раствор чище и, кажется, работает лучше. Просто замените код будет onoptionsitemselected с этим:
@Override
public boolean onSupportNavigateUp() {
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
// handle up navigation
return true;
} else {
return super.onSupportNavigateUp();
}
}