DrawerLayout
在Android开发中,DrawerLayout(以下简称DL)是Material Design中实现滑动菜单需要使用的控件。
滑动菜单现在在很多应用中很常见,Google为了推广MD设计风格,在Google Play等应用上也使用了很多MD设计。
那么,怎么才能实现滑动菜单设计呢?
具体实现
滑动菜单其实是将菜单项隐藏,然后设置为通过滑动等方式使它显示出来。这样可以在显示菜单、完成一系列功能的同时主屏幕空间,使整个应用界面显得简洁。
DL是可以简单地认为是一种布局,它需要放在布局的最外层,而且它只能有两个子项(子项可以是其余Layout,可以在其中嵌套其他内容)。
这时需要在里面放入两个布局,一个是在主屏幕上显示的内容,第二个是滑动菜单显示的内容。
我在DL中放入了一个CoordinatorLayout和一个NavigationView,其中前者属于一个加强版的FrameLayout,里面嵌套了一个ToolBar,而后者是Design Support中的一个控件,它严格按照Material Design设计,可以使我们的界面变得非常美观。
因为它来自Design Support库,因此我们需要在Gradle文件中添加下列内容。
compile 'com.android.support:design:26.1.0'
compile 'de.hdodenhof:circleimageview:2.1.0'
前者是Design Support库,而后者是一个非常好用的图像圆形化控件,可以很简单地把我们的图片变成圆形。
在NavigationView中,我们必须设置android:layout_gravity这个属性,最好设置为start来代替left,因为这样系统会根据手机使用的语言来决定菜单是从左侧划出还是右侧 。从左到右的语言,如汉语、英语会从左侧划出,而阿拉伯语这些从右到左的语言则是从右侧划出。
这里我们使用了app命名空间,其中app:menu是用来指定滑动菜单的内容,而app:headerLayout则是滑动菜单开头的那个部分,就像这张图片中显示头像、姓名、邮箱的布局。
接下来我们在res/menu下建立一个nav_menu.xml文件,在res/layout下建立nav_header.xml文件。两个文件的内容如下,大家也可以自己定义。
nav_header.xml :
在de.hdodenhof.circleimageview.CircleImageView中,我使用了一张已经保存好的图片。
nav_menu :
android:checkableBehavior="single"表示所有项目只能单选。
接下来就该实现NavigationView的点击事件了:
public class MainActivity extends AppCompatActivity {
private DrawerLayout drawerLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//设置ToolBar
Toolbar toolbar = findViewById(R.id.toolBar_main);
setSupportActionBar(toolbar);
//设置DrawerLayout在ToolBar中的启动按钮
drawerLayout = findViewById(R.id.drawer_main);
ActionBar actionBar = getSupportActionBar();
if(actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeAsUpIndicator(R.drawable.ic_menu_);
}
//设置NavigationView中菜单项的点击事件
NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setCheckedItem(R.id.nav_menu_mainp);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
//此处作用为适配点击更换Fragment
switch (item.getItemId()){
case R.id.nav_menu_mainp:
replaceFragment(new MainFragment());
break;
case R.id.nav_menu_booksp :
replaceFragment(new BookFragment());
break;
case R.id.nav_menu_newsp :
replaceFragment(new NewsFragment());
break;
case R.id.nav_menu_settingsp :
replaceFragment(new SettingsFragment());
break;
case R.id.nav_menu_aboutp :
replaceFragment(new AboutFragment());
break;
case R.id.nav_menu_givingp :
replaceFragment(new GivingFragment());
break;
default:
break;
}
drawerLayout.closeDrawers();
return true;
}
});
//设置动态添加Fragment达到切换界面的目的
replaceFragment(new MainFragment());
}
//ToolBar及所有菜单功能的实现
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_toolbar_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home :
drawerLayout.openDrawer(GravityCompat.START);
break;
default:
}
return true;
}
//Fragment的replace方法定义,更换Fragment的方法
private void replaceFragment(Fragment fragment) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.main_framelayout, fragment);
transaction.commit();
}
}
以上代码中,我还完成了一些功能的实现:
- 设置了ToolBar中打开DL的按钮
- 对每一个选项设置了点击事件,切换Fragment,点击后关闭DL
这样,一个完美的DrawerLayout程序设计完成。
效果图: