изменить выбранный элемент навигационного ящика при изменении заднего стека фрагмента

У меня есть два фрагмента FragmentHome и FragmentAbout, я добавил NavigationDrawer в приложение, когда я нажимаю Home, он открывает FragmentHome, а About открывает FragmentAbout, когда я открываю FragmentAbout, я также добавляю его в backstack. Это работает нормально.

Теперь проблема в том, что когда я нажимаю на About и нажимаю кнопку «Назад», он переходит к FragmentHome, но NavigationDrawer по-прежнему показывает About как выбранный элемент, я хочу изменить этот выбранный элемент на Home, когда я нажимаю кнопку «Назад» из FragmentAbout

Домашняя деятельность:

public class ActivityHome extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {

Toolbar toolbar;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_home);

    // Toolbar
    toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    // Drawer layout
    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.nav_drawer_layout);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.nav_drawer_open, R.string.nav_drawer_close);
    assert drawer != null;
    drawer.setDrawerListener(toggle);
    toggle.syncState();

    // Navigation view
    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    assert navigationView != null;
    navigationView.setNavigationItemSelectedListener(this);

    // Open first menu item
    navigationView.getMenu().performIdentifierAction(R.id.nav_home, 0);

    // Set first item checked
    navigationView.setCheckedItem(R.id.nav_home);
}

@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {

    final MenuItem menuItem = item;

    // Check if menu item is selected
    if (item.isChecked())
        item.setChecked(false);
    else
        item.setChecked(true);

    // Handle navigation view item clicks here.
    int id = item.getItemId();

    if (id == R.id.nav_home) {

        // Open home fragment
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.frame_layout, new FragmentHome())
                .commit();

    } else if (id == R.id.nav_about) {

        toolbar.setTitle("About");

        // Open home fragment
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.frame_layout, new FragmentAbout())
                .addToBackStack(null)
                .commit();

    }

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.nav_drawer_layout);
    assert drawer != null;
    drawer.closeDrawer(GravityCompat.START);
    return true;
}

@Override
public void onBackPressed() {
    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.nav_drawer_layout);
    assert drawer != null;
    if (drawer.isDrawerOpen(GravityCompat.START)) {
        drawer.closeDrawer(GravityCompat.START);
    } else {
        super.onBackPressed();
    }
}}

ФрагментГлавная

public class FragmentHome extends Fragment {

public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    return inflater.inflate(R.layout.fragment_home, container, false);
}

@Override
public void onResume() {
    super.onResume();
    ((AppCompatActivity)getActivity()).getSupportActionBar().setTitle(R.string.fragment_home_title);
}
}

Код FragmentAbout такой же, как и FragmentHome, только макет изменен.

Я много искал в stackoverflow, но пока не нашел решения, поэтому, если кто-то знает, как это сделать, сообщите мне.


comment
NavigationDrawer по-прежнему показывает элемент «О выбранном элементе»... для этого вы говорите о заголовке панели инструментов ??????   -  person Saurabh Vardani    schedule 10.05.2016
comment
@Saurabh Нет, это не заголовок панели инструментов, заголовок панели инструментов работает должным образом, я хочу изменить выделенный пункт меню в ящике на Home.   -  person DCK    schedule 11.05.2016
comment
ты нашел это ??   -  person Venkat Ramana    schedule 15.12.2016


Ответы (3)


Для этого можно использовать OnBackStackChangedListener. Пробовал, работает отлично.

public Fragment getCurrentFragment() {
    return this.getSupportFragmentManager().findFragmentById(R.id.fragment_container);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
   ...
   this.getSupportFragmentManager().addOnBackStackChangedListener(
       new FragmentManager.OnBackStackChangedListener() {
          public void onBackStackChanged() {
              Fragment current = getCurrentFragment();
              if (current instanceof MyFragmentA) {
                 navigationView.setCheckedItem(R.id.nav_myfragA);
              } else {
                 navigationView.setCheckedItem(R.id.nav_myfragB);
           }
       }
   });
...
}
person Stephane    schedule 28.08.2016
comment
Этот способ работает, но если использовать один и тот же фрагмент для разных предметов, будет ошибка. Также, если вы откроете DialogFragment (вместо фрагмента) и закроете его, это событие не будет вызвано. - person CoolMind; 08.02.2017
comment
@CoolMind для одинаковых фрагментов, вы можете сравнить теги - person Amir; 10.02.2017

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

private List<Integer> itemPositionStacks = new ArrayList<>();

protected void onCreate(@Nullable Bundle savedInstanceState) {
    itemPositionStacks.add(currentSelectedPosition);
}

public void onNavigationViewItemSelected(int itemId) {
        Fragment fr = null;
        switch (itemId) {
            case 0:
                fr = new aFragment();
                break;
            case 1:
                fr = new bFragment();
                break;
        }

        getSupportFragmentManager().beginTransaction()
                .replace(R.id.container, fr)
                .addToBackStack(null)
                .commit();

        Drawer.getInstance().setDrawerChecked(itemId);
        itemPositionStacks.add(itemId);
    }

public void onBackPressed() {
        if(itemPositionStacks.size() > 1) {
            itemPositionStacks.remove(itemPositionStacks.size() - 1);
            Drawer.getInstance().setDrawerChecked(itemIdStacks.get(itemIdStacks.size() - 1));
        }
        super.onBackPressed();
    }
person Dark Leonhart    schedule 17.06.2016

В вашей функции onBackPressed().. вы должны выбрать, какой элемент выбрать, используя

drawer.setCheckedItem(R.id.nav_home);

и снимите выделение с другого элемента

drawer.getMenu().findItem(R.id.nav_about).setChecked(false);
person Abanoub Samaan    schedule 10.05.2016