【问题标题】:How to disable or hide a Drawer Layout from Fragment Android如何从 Fragment Android 禁用或隐藏抽屉布局
【发布时间】:2015-12-21 11:45:47
【问题描述】:

我的应用程序中有 10 个不同的片段。我需要在几个片段中隐藏导航抽屉(抽屉布局),如何从片段中访问抽屉布局并隐藏它?我知道我们需要在活动中使用mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);,但是如何在片段中使用呢?

【问题讨论】:

    标签: android


    【解决方案1】:

    你可以在你的 Fragment 中做这样的事情:

    private MainActivity main;
    
    @Override
        public void onAttach(Activity activity) {
            super.onAttach(activity);
            main = (MainActivity) activity;
        }
    

    你绝对应该避免这种情况!

    更好的解决方案是使用接口在 Main 和 Fragment 之间进行通信。你最终会得到这样的结果:

    public interface MyInterface {
     public void lockDrawer();
     public void unlockDrawer();
    }
    

    主要:

    public class DetailViewActivity extends AppCompatActivity implements MyInterface {
     @Override
        public void lockDrawer() {         
          mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
        }
    
     @Override
        public void unlockDrawer() {
         mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
        }
    
    }
    

    片段:

       public class MyFragment extends Fragment {
         private MyInterface myInterface;
    
         @Override
         public void onAttach(Activity activity) {
          super.onAttach(activity);
           try {
            myInterface = (MyInterface) activity;
               } catch (ClassCastException e) {
                  throw new ClassCastException(activity.toString() + " must implement MyInterface");
                }
            }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
            // Inflate the layout for this fragment
            myInterface.lockDrawer();
            return inflater.inflate(R.layout.example_fragment, container, false);
        }
    
        @Override
        public void onDestroyView() {
            super.onDestroyView();
            myInterface.unlockDrawer();
        }
    
    }
    

    为什么这是最佳解决方案:如果您执行 ((HomeActivity) mActivity) 之类的操作,您将无法重复使用 Fragment。 会有一个 ClassCastException。为了重用您的 Fragment,您应该使用接口而不是强制转换 MainActivity。所以每个将使用的活动 你的 Frament 可以简单地实现这个接口。即使没有 DrawerLayout 你也可以使用它。所以最大的努力是可重用性。

    【讨论】:

      【解决方案2】:

      带有导航组件的 KOTLIN 解决方案:

      如果您使用导航组件(具有多个片段目的地的一个主要活动),那么您需要使用 addOnDestinationChangedListener 来处理您将显示哪个片段以及将您的导航视图隐藏在抽屉布局中。

      这里你可以看到如何从navigation component开始,这里是关于setDrawerLockMode方法。

      所以你的代码看起来像这样:

       val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
       val navController = findNavController(R.id.nav_host_fragment)
       navController.addOnDestinationChangedListener{_, destination, _ ->
      
       if (destination.id == R.id.nav_fragment1) {
           drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
           //DRAWER LOCKED IN fragment1
          
       } else if (destination.id == R.id.nav_fragment2) {
                 drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
                 //DRAWER UNLOCKED IN fragment2
          
       } else {.....
                 
       }
       }
      

      这部分代码你可以放在你的 MainActivity 的 onCreate() 方法中。 制作导航抽屉活动的最简单方法是在您的 android 工作室中自动进行。只需按照文件 -> 新建 -> 活动 -> 导航抽屉活动。

      【讨论】:

        【解决方案3】:

        您可以通过以下方式做到这一点 -

        在您的活动中编写一个公共方法,如下所示 -

        public void enableDisableDrawer(int mode) {
            if (mDrawerLayout != null) {
                mDrawerLayout.setDrawerLockMode(mode);
            }
        }
        

        然后在片段的onResume 中,您可以调用它并根据需要更改抽屉锁定模式 -

        ((HomeActivity) mActivity).enableDisableDrawer(DrawerLayout.LOCK_MODE_UNLOCKED);
        

        ((HomeActivity) mActivity).enableDisableDrawer(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
        

        mActivity 是我的活动参考。

        这种方式对我有用。

        【讨论】:

        • 我不推荐这个原因——这样你就失去了 Fragments 的可重用性
        【解决方案4】:

        您可以使用此方法锁定或解锁抽屉:DrawerLayout.setDrawerLockMode(...)。 (该方法还有其他两个版本可以为特定抽屉指定锁定模式。)要锁定,请使用DrawerLayout.LOCK_MODE_LOCKED_CLOSED;要解锁,请使用DrawerLayout.LOCK_MODE_UNLOCKED

        如果您使用的是 ActionBarDrawerToggle,则需要添加一些额外的代码,以防止在您锁定抽屉时单击 ActionBarDrawerToggle 时抽屉打开。

        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            // check lock mode before passing to ActionBarDrawerToggle
            // I assume your drawer is on the left; if not, use Gravity.RIGHT
            int lockMode = mDrawer.getDrawerLockMode(Gravity.LEFT);
            if (lockMode == DrawerLayout.LOCK_MODE_UNLOCKED &&
                    mDrawerToggle.onOptionsItemSelected(item)) {
                return true;
            }
            // Handle your other action bar items...
        
            return super.onOptionsItemSelected(item);
        }
        

        更多信息请参考链接link here

        【讨论】:

        • 我知道这一点。我的问题是,我怎样才能从活动中访问它而不是从片段中访问它。
        【解决方案5】:

        在您的活动中创建两个方法。一个用于打开抽屉,另一个用于关闭它。请参阅下面的代码。

        public class MainActivity extends AppCompatActivity {
            private DrawerLayout mDrawerLayout;
            .......
        
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                .........
                mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
                .........
            }
            public void openNavigationDrawer() {
                mDrawerLayout.openDrawer(Gravity.LEFT);
            }
        
            public void closeNavigationDrawer() {
                mDrawerLayout.closeDrawer(Gravity.LEFT);
            }
        
            public void lockNavigationDrawer() {
                mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
            }
        
            public void unLockNavigationDrawer() {
                mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
            }
        }
        

        现在从您的片段中调用上述方法,如下所示

        ((MainActivity)getActivity()).closeNavigationDrawer(); // to close drawer
        ((MainActivity)getActivity()).openNavigationDrawer(); // to open drawer
        ((MainActivity)getActivity()).lockNavigationDrawer(); // to lock drawer
        ((MainActivity)getActivity()).unLockNavigationDrawer(); // to unlock drawer
        

        【讨论】:

        • 这行得通。这也不是好的做法 - 对于 Activity 和 Fragments 之间的通信,您应该始终使用接口
        【解决方案6】:

        您可以使用此方法来锁定或解锁抽屉:DrawerLayout.setDrawerLockMode(...)。 (该方法还有其他两个版本可以为特定抽屉指定锁定模式。)要锁定,请使用 DrawerLayout.LOCK_MODE_LOCKED_CLOSED;要解锁,请使用 DrawerLayout.LOCK_MODE_UNLOCKED。

        如果您使用的是 ActionBarDrawerToggle,则需要添加一些额外的代码,以防止在您锁定抽屉时单击 ActionBarDrawerToggle 时抽屉打开。

        enter code here
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
        // check lock mode before passing to ActionBarDrawerToggle
        // I assume your drawer is on the left; if not, use Gravity.RIGHT
        int lockMode = mDrawer.getDrawerLockMode(Gravity.LEFT);
        if (lockMode == DrawerLayout.LOCK_MODE_UNLOCKED &&
                mDrawerToggle.onOptionsItemSelected(item)) {
            return true;
        }
        // Handle your other action bar items...
        
        return super.onOptionsItemSelected(item);
        }
        

        【讨论】:

          【解决方案7】:

          我为此苦苦挣扎了好几个小时:将 DrawerLayout 设置为锁定模式根本不适合我。即使按照你的例子。

          最后我想出了这个post

          DrawerLayout.setDrawerLockMode 将不起作用如果您设置 layout_gravity 例如到 NavigationView 中的 start|bottom。只需将其设置为 startend

          希望这对某人有所帮助

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-01-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-11-04
            • 1970-01-01
            • 2015-11-02
            相关资源
            最近更新 更多