一、DrawerLayout是一个拥有两个子控件的布局,第一个子控件是主屏幕中显示的内容,第二个子控件是滑动菜单中显示的内容:
1 <android.support.v4.widget.DrawerLayout 2 xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:app="http://schemas.android.com/apk/res-auto" 4 android:id="@+id/drawer_layout" 5 android:layout_width="match_parent" 6 android:layout_height="match_parent" 7 > 8 9 <FrameLayout 10 android:layout_width="match_parent" 11 android:layout_height="match_parent"> 12 13 <android.support.v7.widget.Toolbar 14 android:id="@+id/toolbar" 15 android:layout_width="match_parent" 16 android:layout_height="?attr/actionBarSize" 17 android:background="?attr/colorPrimary" 18 android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" 19 app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/> 20 21 </FrameLayout> 22 <TextView 23 android:layout_width="match_parent" 24 android:layout_height="match_parent" 25 android:layout_gravity="start" 26 android:text="这是一个菜单" 27 android:textSize="30sp" 28 android:background="#FFF"/> 29 </android.support.v4.widget.DrawerLayout>
要注意的地方是第二个子控件TextView的layout_gravity属性指定的是滑动菜单是在屏幕的左边还是右边,属性值使用right或者left,这里使用start表示根据系统语言进行判断。
这里的效果是这样:
然后在标题栏上加入一个导航按钮,点击导航按钮也能打开滑动菜单,具体实现原理是,标题栏左方本来就有一个叫作HomeAsup的按钮,它默认的图标是一个返回的箭头,含义是返回上一个活动,所以只需要将它显示出来,修改它的图标和点击事件即可。
具体java代码:
1 public class MainActivity extends AppCompatActivity { 2 3 private DrawerLayout mDrawerLayout; 4 @Override 5 protected void onCreate(Bundle savedInstanceState) { 6 super.onCreate(savedInstanceState); 7 setContentView(R.layout.activity_main); 8 Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 9 setSupportActionBar(toolbar); 10 mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); 11 ActionBar actionBar = getSupportActionBar(); 12 if(actionBar != null){ 13 //让ActionBar的HomeAsUp按钮显示出来 14 actionBar.setDisplayHomeAsUpEnabled(true); 15 //改变HomeAsUp按钮的图标 16 actionBar.setHomeAsUpIndicator(R.drawable.ic_action_name); 17 } 18 19 } 20 ... 21 public boolean onOptionsItemSelected(MenuItem item){ 22 switch (item.getItemId()){ 23 case android.R.id.home: 24 mDrawerLayout.openDrawer(GravityCompat.START); 25 break; 26 ... 27 default: 28 break; 29 } 30 return true; 31 } 32 }
HomeAsup的id永远都是android.R.id.home,mDrawerLayout.openDrawer(GravityCompat.START)调用这个方法就可以打开滑动菜单。
二、 在滑动菜单中定制任意的布局——使用NavigationView
使用这个NavigationView先要添加一个库,
compile 'com.android.support:design:26.0.0-alpha1'
这里为了一个图片圆形化的功能我又添加了另一个库
compile 'de.hdodenhof:circleimageview:2.1.0'
把DrawerLayout的第二个子控件换成NavigationView,具体代码如下:
1 <android.support.v4.widget.DrawerLayout 2 xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:app="http://schemas.android.com/apk/res-auto" 4 android:id="@+id/drawer_layout" 5 android:layout_width="match_parent" 6 android:layout_height="match_parent" 7 > 8 9 <FrameLayout 10 android:layout_width="match_parent" 11 android:layout_height="match_parent"> 12 13 <android.support.v7.widget.Toolbar 14 android:id="@+id/toolbar" 15 android:layout_width="match_parent" 16 android:layout_height="?attr/actionBarSize" 17 android:background="?attr/colorPrimary" 18 android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" 19 app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/> 20 21 </FrameLayout> 22 <android.support.design.widget.NavigationView 23 android:id="@+id/nav_view" 24 android:layout_width="match_parent" 25 android:layout_height="match_parent" 26 android:layout_gravity="start" 27 app:menu="@menu/nav_menu" 28 app:headerLayout="@layout/nav_header"> 29 30 </android.support.design.widget.NavigationView> 31 </android.support.v4.widget.DrawerLayout>
app:menu和app:headerLayout两个属性分别指定了NavigationView的具体菜单项和头部布局,这里只是先写好一个名字,还需要去创建这样两个布局文件:
菜单项:
1 <menu xmlns:app="http://schemas.android.com/apk/res-auto" 2 xmlns:android="http://schemas.android.com/apk/res/android"> 3 4 <group android:checkableBehavior="single"> 5 <item 6 android:id="@+id/nav_call" 7 android:icon="@drawable/nav_call" 8 android:title="Call" /> 9 <item 10 android:id="@+id/nav_friend" 11 android:icon="@drawable/nav_friend" 12 android:title="Friend" /> 13 <item 14 android:id="@+id/nav_location" 15 android:icon="@drawable/nav_location" 16 android:title="Location" /> 17 <item 18 android:id="@+id/nav_mail" 19 android:icon="@drawable/nav_mail" 20 android:title="Mail" /> 21 <item 22 android:id="@+id/nav_task" 23 android:icon="@drawable/nav_task" 24 android:title="Task" /> 25 </group> 26 </menu>
</menu>里嵌套了一个</group>,然后将group的checkableBehavior属性设置为single表示所有的菜单只能单选。
然后是头部布局:
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 android:orientation="vertical" 3 android:layout_width="match_parent" 4 android:layout_height="180dp" 5 android:padding="10dp" 6 android:background="?attr/colorPrimary"> 7 8 <de.hdodenhof.circleimageview.CircleImageView 9 android:id="@+id/icon_image" 10 android:layout_width="70dp" 11 android:layout_height="70dp" 12 android:src="@drawable/nac_icon" 13 android:layout_centerInParent="true"/> 14 15 <TextView 16 android:id="@+id/mail" 17 android:layout_width="wrap_content" 18 android:layout_height="wrap_content" 19 android:layout_alignParentBottom="true" 20 android:text="943217258@qq.com" 21 android:textSize="14sp" 22 android:textColor="#FFF"/> 23 24 <TextView 25 android:id="@+id/username" 26 android:layout_width="wrap_content" 27 android:layout_height="wrap_content" 28 android:layout_above="@id/mail" 29 android:text="一个名字" 30 android:textSize="14sp" 31 android:textColor="#FFF"/> 32 </RelativeLayout>
最终效果:
最后就是菜单项的点击事件了,直接改java代码就行:
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view); navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() { @Override public boolean onNavigationItemSelected(MenuItem item) { switch (item.getItemId()){ case R.id.nav_call: Intent intent = new Intent(MainActivity.this,Main2Activity.class); startActivity(intent); break; } return true; } });