【发布时间】:2015-12-21 11:45:47
【问题描述】:
我的应用程序中有 10 个不同的片段。我需要在几个片段中隐藏导航抽屉(抽屉布局),如何从片段中访问抽屉布局并隐藏它?我知道我们需要在活动中使用mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);,但是如何在片段中使用呢?
【问题讨论】:
标签: android
我的应用程序中有 10 个不同的片段。我需要在几个片段中隐藏导航抽屉(抽屉布局),如何从片段中访问抽屉布局并隐藏它?我知道我们需要在活动中使用mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);,但是如何在片段中使用呢?
【问题讨论】:
标签: android
你可以在你的 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 你也可以使用它。所以最大的努力是可重用性。
【讨论】:
带有导航组件的 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 工作室中自动进行。只需按照文件 -> 新建 -> 活动 -> 导航抽屉活动。
【讨论】:
您可以通过以下方式做到这一点 -
在您的活动中编写一个公共方法,如下所示 -
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 是我的活动参考。
这种方式对我有用。
【讨论】:
您可以使用此方法锁定或解锁抽屉: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
【讨论】:
在您的活动中创建两个方法。一个用于打开抽屉,另一个用于关闭它。请参阅下面的代码。
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
【讨论】:
您可以使用此方法来锁定或解锁抽屉: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);
}
【讨论】:
我为此苦苦挣扎了好几个小时:将 DrawerLayout 设置为锁定模式根本不适合我。即使按照你的例子。
最后我想出了这个post
DrawerLayout.setDrawerLockMode 将不起作用如果您设置 layout_gravity 例如到 NavigationView 中的 start|bottom。只需将其设置为 start 或 end
希望这对某人有所帮助
【讨论】: