在片段后台更改上更改导航抽屉选定项目

时间:2016-05-10 09:55:09

标签: android android-fragments navigation-drawer fragmenttransaction fragment-backstack

我有两个片段FragmentHomeFragmentAbout,当我点击NavigationDrawer时,我已向应用添加了Home FragmentHomeAbout打开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();
    }
}}

FragmentHome

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上搜索了很多,但还没有找到任何解决方案,所以如果有人知道怎么做,请告诉我。

3 个答案:

答案 0 :(得分:11)

您可以使用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);
           }
       }
   });
...
}

答案 1 :(得分:0)

这可能不是一个好的解决方案,但至少它对我来说是可以接受的。每当从导航抽屉单击片段菜单时,您需要将片段的位置存储在堆栈变量(ex:List)中。然后重写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();
    }

答案 2 :(得分:-2)

在你的onBackPressed()函数中.. 您必须使用

选择要选择的项目
drawer.setCheckedItem(R.id.nav_home);

并删除其他项目的选择

drawer.getMenu().findItem(R.id.nav_about).setChecked(false);