如何在打开特定碎片时隐藏导航抽屉?

13

我在安卓开发方面很新手。我希望在用户未登录时隐藏导航抽屉。因此,它将显示登录片段(最好是全屏显示,就像Facebook Android一样)。如果用户已经登录,导航抽屉将始终显示。

MainActivity.java

public class MainActivity extends AppCompatActivity {

private DrawerLayout navDrawerLayout;
private Toolbar toolbar;
private ActionBarDrawerToggle navDrawerToggle;

private SharedPreferences pref;

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

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

    navDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

    // Find our drawer view
    NavigationView navDrawerView = (NavigationView) findViewById(R.id.navdrawer_view);
    // Setup drawer view
    setupDrawerContent(navDrawerView);

    navDrawerToggle = setupDrawerToggle();

    pref = getPreferences(0);
    initFirstFrame();
}

private ActionBarDrawerToggle setupDrawerToggle() {
    return new ActionBarDrawerToggle(this, navDrawerLayout, toolbar, R.string.drawer_open,  R.string.drawer_close);
}

private void setupDrawerContent(NavigationView navDrawerView) {
    navDrawerView.setNavigationItemSelectedListener(
            new NavigationView.OnNavigationItemSelectedListener() {
                @Override
                public boolean onNavigationItemSelected(MenuItem menuItem) {
                    selectDrawerItem(menuItem);
                    return true;
                }


            });
}

public void selectDrawerItem(MenuItem menuItem) {
    // Create a new fragment and specify the fragment to show based on nav item clicked
    Fragment fragment = null;
    Class fragmentClass;
    switch(menuItem.getItemId()) {
        case R.id.events:
            fragmentClass = EventsFragment.class;
            break;
        case R.id.pengumuman:
            fragmentClass = NewsFragment.class;
            break;
        case R.id.edit_profil:
            fragmentClass = ProfileFragment.class;
            break;
        default:
            fragmentClass = EventsFragment.class;
    }

    try {
        fragment = (Fragment) fragmentClass.newInstance();
    } catch (Exception e) {
        e.printStackTrace();
    }

    // Insert the fragment by replacing any existing fragment
    FragmentManager fragmentManager = getSupportFragmentManager();
    fragmentManager.beginTransaction().replace(R.id.frame_content, fragment).commit();

    // Highlight the selected item has been done by NavigationView
    menuItem.setChecked(true);
    // Set action bar title
    setTitle(menuItem.getTitle());
    // Close the navigation drawer
    navDrawerLayout.closeDrawers();
}

private void initFirstFrame(){
    Fragment fragment;
    if(pref.getBoolean(Constants.IS_LOGGED_IN,false)){
        fragment = new ProfileFragment();
    }else {
        fragment = new LoginFragment();
        // in this login fragment, navdrawer should be invisible, the toolbar too I guess
    }

    FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    fragmentTransaction.replace(R.id.frame_content,fragment);
    fragmentTransaction.commit();
}


@Override
public boolean onOptionsItemSelected(MenuItem item) {
    return navDrawerToggle.onOptionsItemSelected(item) || super.onOptionsItemSelected(item);
}

// 'onPostCreate' called when activity start-up is complete after 'onStart()'
// NOTE! Make sure to override the method with only a single 'Bundle' argument
@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    // Sync the toggle state after onRestoreInstanceState has occurred
    navDrawerToggle.syncState();
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    // Pass any configuration change to the drawer toggles
    navDrawerToggle.onConfigurationChanged(newConfig);
}

}

使用LoginActivity和MainActivity,其中导航抽屉位于MainActivity中,而Login则没有。这就是我所做的。 - Vucko
@Vucko 如果我这样做了,那么如何将用户输入的每个数据解析到我的MainActivity中呢?正如您所看到的,我有一个ProfileFragment,用户可以在其中编辑电子邮件、密码等。抱歉,我是初学者,对意图(Intent)的事情不太清楚。 - adadion
你需要学习,不要因为对某些事情不熟悉而回避它们。你可以在网上找到基本上任何东西。我建议你在网上搜索有关登录的教程,并查看并学习 Android Studio 中名为“登录活动”的模板。 - Vucko
1
最好的在片段和活动之间通信的方式是通过接口。它有助于代码重用,并且可以在片段之间进行交互使用。请查看Google上的片段间通信。我的答案会给你一个方向的提示 :) - Kushan
3个回答

23

定义一个名为 DrawerLocker 的接口:

interface DrawerLocker{
   public void setDrawerLocked(boolean shouldLock);
}

在包含NavigationDrawer的Activity中实现此接口,并覆盖此方法。

class YourActivity implements DrawerLocker{
...
...
public void setDrawerLocked(boolean enabled){
    if(enabled){
        drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
    }else{
        drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
    }

}

现在,在您的Fragment的onCreateView方法中,调用以下方法:

 ((DrawerLocker)getActivity()).setDrawerLocked(true);
在 Fragment 的 onDestroyView 方法中,重新启用抽屉布局:
((DrawerLocker)getActivity()).setDrawerLocked(false);

注意:如果您决定在另一个活动中重复使用此片段,请确保实现接口。如果该活动没有导航抽屉,请实现一个空方法。 - Kushan
1
嗨,抱歉那是个打错字了:应该是一个方法调用 -> getActivity()。很高兴它能帮到你。 - Kushan
1
@Kushan 哇,你太棒了...+1000 谢谢你,伙计,非常感谢...谢谢谢谢谢谢... - Gowthaman M
随时可以,伙计 :) - Kushan
1
这个答案对我也没用。但是这个可以:https://dev59.com/xIfca4cB1Zd3GeqPouC7#33003163 - ban-geoengineering

3

在Activity的onCreate方法中加入以下代码,可以在栈中有多个Fragment时阻止抽屉打开:

 getSupportFragmentManager().addOnBackStackChangedListener(() -> {
        if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
        } else {
            drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
        }
    });

1

这就是你所需要的,在if条件语句中检查目标位置,如果不需要抽屉则不显示

单一活动架构,将以下代码放在活动的onCreate函数中

private fun changeDrawerState() {
    val navHostFragment = supportFragmentManager
        .findFragmentById(R.id.nav_host_fragment) as NavHostFragment
    val drawer = findViewById<DrawerLayout>(R.id.drawer_layout)
    navHostFragment.navController.addOnDestinationChangedListener(listener = { _, destination, _ ->
        //set in case app asked for verify auth, signIn page drawer will be locked
        if (destination.id== R.id.signInFragment) {
            drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
        } else if (drawer.getDrawerLockMode(GravityCompat.START) != DrawerLayout.LOCK_MODE_UNLOCKED) {
            drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
        }
    })
}

根据抽屉打开的方向,使用GravityCompat.START。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接