侧滑菜单
DrawerLayout滑动出来的菜单,我们可以自己写一些觉得不错的布局。(如果对DrawerLayout陌生的话请点击这篇博客:Android Material Design DrawerLayout)
也可以使用Google最新推出规范式设计中的NavigationView和DrawerLayout结合实现侧滑菜单栏效果,NavigationView继承自FrameLayout。一般用于应用的导航菜单,菜单的内容来自于menu文件。所谓的谷歌设计思想估计就是这样咯!风格上得到一个大致统一的美观,同时也给程序员节省时间。
NavigationView是帮助DrawerLayout管理侧滑菜单的布局,所以NavigationView由两部分组成,一个头部布局HeaderView,一个是menu文件夹下的内容布局。
使用NavigationView。我们需要添加依赖包:
compile 'com.android.support:design:23.4.0'
咱们还是从例子中更好的去了解NavigationView吧!
头部布局HeaderView:右击layout--New---Layout resource file创建一个新的文件header_layout.xml。
<?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="200dp" android:orientation="vertical"> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/imageView" android:scaleType="centerCrop" android:src="@drawable/pigu"/> </LinearLayout>
menu文件夹下的内容布局:右击res文件夹--New--Directory,创建一个menu文件夹;然后右击menu文件夹--New--Layout resource file创建一个新的文件nav_menu.xml
<?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/nav_more" android:icon="@drawable/ic_more" android:title="more" /> <item android:id="@+id/nav_left" android:icon="@drawable/ic_left" android:title="left"/> <item android:id="@+id/nav_delete" android:icon="@drawable/ic_delete" android:title="delete"/> <item android:id="@+id/nav_share" android:icon="@drawable/ic_share_black" android:title="share"/> <item android:id="@+id/nav_de" android:icon="@drawable/ic_dehaze" android:title="de"/> </group> </menu>
侧滑菜单DrawerLayout布局:layout_drawerlayout.xml
<?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/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent"> </FrameLayout> <android.support.design.widget.NavigationView android:id="@+id/navigation_view" android:layout_width="322dp" android:layout_height="match_parent" android:layout_gravity="start" app:headerLayout="@layout/header_layout" app:menu="@menu/nav_menu"> </android.support.design.widget.NavigationView> </android.support.v4.widget.DrawerLayout>
其中:
- android:layout_gravity可设置抽屉,也就是NavigationView从左边或是右边打开。
- app:menu用于设置菜单内容的xml布局。
- app:headerLayout用于设置NavigationView的HeaderView的xml布局文件。
最后是主布局:activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.dell.navigationview.MainActivity"> <!--DrawerLayout--> <include layout="@layout/layout_drawerlayout"/> </LinearLayout>
Java代码没有写什么代码,就不贴了,直接运行看效果:
NavigationView点击事件:分为两种点击事件,一种是头部布局点击事件,另一种是内容布局的点击事件。
一:头部事件:
处理头部点击事件,我们需要先获得到头部控件,在Java代码中我们可以通过下面的方式获得头部控件,然后通过调用headerView中的findViewById方法来查找到头部的控件,设置点击事件即可。
//获取头布局文件 View headerView = mNavigationView.getHeaderView(0);
二:内容事件:Java代码
public class MainActivity extends AppCompatActivity { private DrawerLayout mDrawerLayout; private NavigationView mNavigationView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initLayout(); } public void initLayout(){ mDrawerLayout=(DrawerLayout) findViewById(R.id.drawer_layout); mNavigationView=(NavigationView) findViewById(R.id.navigation_view); //将more菜单项设置为默认选中 mNavigationView.setCheckedItem(R.id.nav_more); mNavigationView.setNavigationItemSelectedListener( new NavigationView.OnNavigationItemSelectedListener() { @Override public boolean onNavigationItemSelected(MenuItem item) { switch (item.getItemId()){ case R.id.nav_more: //逻辑代码想干啥干啥 break; case R.id.nav_left: //逻辑代码想干啥干啥 break; case R.id.nav_delete: //逻辑代码想干啥干啥 break; case R.id.nav_share: //逻辑代码想干啥干啥 break; case R.id.nav_de: //逻辑代码想干啥干啥 break; } return true; } }); } }
NavigationView依附于DrawerLayout,而DrawerLayout又常常和Toolbar一起使用,三个控件一起使用,效果没得说的。在上面例子的基础上,我们来一个NavigationView+DrawerLayout+Toolbar例子:(如果对Toolbar陌生的话请点击这篇博客:Android Material Design Toolbar)
这里我们写入Toolbar控件就好!新增布局:
layout_toolbar.xml
<?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" android:popupTheme="@style/ThemeOverlay.AppCompat.Light" xmlns:android="http://schemas.android.com/apk/res/android"> </android.support.v7.widget.Toolbar>
主布局也要将这个新增的布局加进来:修改主布局
activity_main.xml
<?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="match_parent" android:orientation="vertical"> <!--Toolbar--> <include layout="@layout/layout_toolbar"/> <!--DrawerLayout--> <include layout="@layout/layout_drawerlayout"/> </LinearLayout>
值得注意的是,Toolbar加进来了,别忘了有些地方需要改改:找到values文件夹下的styles.xml文件,把parent这个属性改下,改为隐藏NoActionBar,
parent="Theme.AppCompat.Light.NoActionBar"
最后修改Java代码:
public class MainActivity extends AppCompatActivity { private DrawerLayout mDrawerLayout; private NavigationView mNavigationView; private Toolbar mToolbar; private ActionBarDrawerToggle mDrawerToggle; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initLayout(); //setSupportActionBar方法将Toolbar实例传入 //其实就是Toolbar替换Actionbar setSupportActionBar(mToolbar); //设置还回键可用 getSupportActionBar().setHomeButtonEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true); //DrawerLayout监听打开/关闭事件 mDrawerToggle=new ActionBarDrawerToggle(this, mDrawerLayout,mToolbar, R.string.open,R.string.close){ @Override public void onDrawerOpened(View drawerView) { super.onDrawerOpened(drawerView); } @Override public void onDrawerClosed(View drawerView) { super.onDrawerClosed(drawerView); } }; mDrawerToggle.syncState(); mDrawerLayout.addDrawerListener(mDrawerToggle); } public void initLayout(){ mToolbar=(Toolbar) findViewById(R.id.toolbar); mDrawerLayout=(DrawerLayout) findViewById(R.id.drawer_layout); mNavigationView=(NavigationView) findViewById(R.id.navigation_view); //将more菜单项设置为默认选中 mNavigationView.setCheckedItem(R.id.nav_more); //NavigationView内容点击事件 mNavigationView.setNavigationItemSelectedListener( new NavigationView.OnNavigationItemSelectedListener() { @Override public boolean onNavigationItemSelected(MenuItem item) { switch (item.getItemId()){ case R.id.nav_more: //逻辑代码想干啥干啥 break; case R.id.nav_left: //逻辑代码想干啥干啥 break; case R.id.nav_delete: //逻辑代码想干啥干啥 break; case R.id.nav_share: //逻辑代码想干啥干啥 break; case R.id.nav_de: //逻辑代码想干啥干啥 break; } return true; } }); } }
效果图: