这是我们 Material Design 系列的第三篇文章了,今天我们来谈谈侧滑菜单,侧滑菜单是很多 APP 中常见的功能效果,今天我们将介绍使用 Material Design 中的 DrawerLayout 和 NavigationView 相结合来实现侧滑栏菜单效果,借助 Google 提供的这些工具实现侧滑的功能将变得异常的简单,侧滑菜单可以将菜单选项隐藏起来,然后可以通过滑动的方式来显示,这样很好的节省了手机屏膜的空间,这也是 Material Design 设计中非常推荐的做法,例如谷歌邮箱 Gmail 就使用了这种设计,接下来我们就来具体的实现这种非常常见的效果,我们先来上效果图吧
下面我们来看一下实现如上界面的布局代码:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#c7c6c6">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="@+id/toolBar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimary"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:titleTextColor="#f5f0f0" />
</RelativeLayout>
<android.support.design.widget.NavigationView
android:id="@+id/navigation"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="left"
app:headerLayout="@layout/navigation_head"
app:menu="@menu/navigation">
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
其实很简单,我们看到最外层是一个 DrawerLayout 控件,是由 suppout-v4 库提供的,首先它是一个布局,在布局中容许放置两个直接的子控件,第一个子控件是主屏幕中显示的内容,第二个子控件是滑动菜单中显示的内容
我们这里放了两个子控件:一个相对布局,然后放置了我们上一次分享的 ToolBar 控件,另一个子控件这里使用了一个NavigationView,其实这里放什么都可以,DrawerLayout 并没有限制使用固定的控件,这里需要注意的是,关于第二个控件,layout_gravity 这个属性是必须制定的,因为我们要告诉 DrawerLayout 滑动菜单是在屏膜的左边还是右边
- left 表示滑动菜单在左边
- right 表示滑动菜单在右边
- start 表示会根据系统语言进行判断
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.1.0'
testCompile 'junit:junit:4.12'
compile 'com.android.support:design:25.1.0'
}
然后我们在 menu 文件夹中创建 navigation 文件,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="@+id/account"
android:icon="@mipmap/account"
android:title="account" />
<item
android:id="@+id/attachment"
android:icon="@mipmap/attachment"
android:title="attachment" />
<item
android:id="@+id/edit"
android:icon="@mipmap/edit"
android:title="edit" />
<item
android:id="@+id/set"
android:icon="@mipmap/set"
android:title="set" />
</group>
</menu>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="160dp"
android:background="#7dd1f0"
android:gravity="center"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="head layout"
android:textSize="40dp" />
</LinearLayout>
这个布局非常简单,就不具体介绍了,这样 headerLayout 布局文件我们就创建好了,然后再通过如下两行代码把我们准备好的 menu 和 headerLayou 设置进去:
app:headerLayout="@layout/navigation_head"
app:menu="@menu/navigation">
/**
* NavigationView 侧滑栏
*/
public class MainActivity extends AppCompatActivity {
private DrawerLayout mDrawerLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
Toolbar toolbar = (Toolbar) findViewById(R.id.toolBar);
setSupportActionBar(toolbar);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);
ActionBar actionBar = getSupportActionBar();
if (actionBar!=null) {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeAsUpIndicator(R.mipmap.category);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.toolbar, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.backup:
Toast.makeText(this, "Click Backup", Toast.LENGTH_LONG).show();
break;
case R.id.delete:
Toast.makeText(this, "Click Delete", Toast.LENGTH_LONG).show();
break;
case R.id.setting:
Toast.makeText(this, "Click Setting", Toast.LENGTH_LONG).show();
break;
case android.R.id.home:
mDrawerLayout.openDrawer(Gravity.LEFT);
break;
default:
}
return true;
}
}
/**
* NavigationView 侧滑栏
*/
public class MainActivity extends AppCompatActivity {
private DrawerLayout mDrawerLayout;
private NavigationView navigationView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
Toolbar toolbar = (Toolbar) findViewById(R.id.toolBar);
setSupportActionBar(toolbar);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);
navigationView = (NavigationView) findViewById(R.id.navigation);
ActionBar actionBar = getSupportActionBar();
if (actionBar!=null) {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeAsUpIndicator(R.mipmap.category);
}
navigationView.setCheckedItem(R.id.account);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
mDrawerLayout.closeDrawers();
//do something
return true;
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.toolbar, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.backup:
Toast.makeText(this, "Click Backup", Toast.LENGTH_LONG).show();
break;
case R.id.delete:
Toast.makeText(this, "Click Delete", Toast.LENGTH_LONG).show();
break;
case R.id.setting:
Toast.makeText(this, "Click Setting", Toast.LENGTH_LONG).show();
break;
case android.R.id.home:
mDrawerLayout.openDrawer(Gravity.LEFT);
break;
default:
}
return true;
}
}