android侧滑菜单笔记
一、SlidingPaneLayout
v4包下的控件,使用简单,功能简洁。官方文档明确说明该控件只能左侧滑动。使用如下:
<android.support.v4.widget.SlidingPaneLayout android:id="@+id/slidingPaneLayout" android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:layout_width="200dp" android:layout_height="match_parent"/> <include layout="@layout/layout_main_content"/> </android.support.v4.widget.SlidingPaneLayout>
SlidingPaneLayout有两个子节点: 第一个为菜单项布局,第二个为内容布局。
java代码中找到该控件,设置监听:
SlidingPaneLayout spl = (SlidingPaneLayout) findViewById(R.id.slidingPaneLayout); if (spl != null) { spl.setPanelSlideListener(new SlidingPaneLayout.PanelSlideListener() { @Override public void onPanelSlide(View panel, float slideOffset) { //正在滑动的监听 } @Override public void onPanelOpened(View panel) { //打开的监听 } @Override public void onPanelClosed(View panel) { //关闭的监听 } }); }
二 DrawerLayout(抽屉效果)
android.support.v4.widget.DrawerLayout android:id="@+id/dl" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ff00ff" android:gravity="start" android:text="主布局内容"/> <TextView android:layout_width="200dp" android:layout_height="match_parent" android:layout_gravity="start" android:background="#00ffff" android:text="侧边菜单栏内容"/> </android.support.v4.widget.DrawerLayout>
Drawerlayout标签中可以有三个子节点,一个是左边菜单,一个是主布局,还有右侧菜单,另外需要在左边菜单起始位置设置为 android:layout_gravity="start",否则会报错
注意:官方手册提示:内容控件必须写在第一个,并且不能含有layout_gravity属性
示例代码如下:
private DrawerLayout dl; private Toolbar toolbar; private ActionBarDrawerToggle actionBarDrawerToggle; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar);//设置标题为当前的Toolbar getSupportActionBar().setHomeButtonEnabled(true);//设置home按钮可用 getSupportActionBar().setDisplayHomeAsUpEnabled(true);//设置显示回到主页的按钮可用,即:返回箭头显示出来 dl = (DrawerLayout) findViewById(R.id.dl);//找到抽屉控件DrawerLayout //创建一个标题栏与抽屉的关联开关 actionBarDrawerToggle = new ActionBarDrawerToggle(this, dl, toolbar, R.string.app_name, R.string.app_name); actionBarDrawerToggle.syncState();//同步抽屉的指示器状态,只有加这一句抽屉的开关才会改变Toolbar上的NavigationIcon图标 dl.addDrawerListener(actionBarDrawerToggle);//添加抽屉监听者,该监听者内部控制了ActionBar的NavigationIcon图标按钮 dl.addDrawerListener(new DrawerLayout.DrawerListener() {//添加开发者自己处理的监听者 @Override public void onDrawerSlide(View drawerView, float slideOffset) { System.out.println("----onDrawerSlide- " + slideOffset); } @Override public void onDrawerOpened(View drawerView) { System.out.println("----onDrawerOpened-"); } @Override public void onDrawerClosed(View drawerView) { System.out.println("----onDrawerClosed-"); } @Override public void onDrawerStateChanged(int newState) { System.out.println("----onDrawerStateChanged- " + newState); } }); }
三、NavigationView
MD的控件,用于解决DrawerLayout中的菜单项设置太麻烦的问题,主流的做法都是用NavigationView来做DrawerLayout的菜单。
用于侧滑菜单中的menu布局。之前Google在V4包中推出自己的 DrawerLayout作为抽屉侧滑菜单,标准使用方法可以参考 google 原生态 抽屉式侧滑菜单 Android DrawerLayout 布局的使用介绍。
当时的官方布局是这样的:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" > <!-- the main content view --> <FrameLayout android:id="@+id/frame_content" android:layout_width="match_parent" android:layout_height="match_parent" > </FrameLayout> <ListView android:id="@+id/drawer_list" android:layout_width="240dp" android:layout_height="match_parent" android:layout_gravity="start" android:background="#9999cc" android:choiceMode="singleChoice" android:divider="@android:color/transparent" android:dividerHeight="0dp" > </ListView> </android.support.v4.widget.DrawerLayout>
其实这次谷歌只是将上面的ListView布局替换成NavigationView了。简化了之前ListView写适配器的繁琐。
先如今布局改成如下:
<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">
<!-- the main content view --> <include layout="@layout/layout_content" />
<!-- the navigetion view --> <android.support.design.widget.NavigationView android:id="@+id/navigationView" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="left" android:fitsSystemWindows="true" app:headerLayout="@layout/layout_header" app:menu="@layout/layout_menu"> </android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
其中NavigationView 中的 android:layout_gravity=”start” 属性来控制抽屉菜单从哪边滑出,一般“start ”从左边滑出,“end”从右边滑出。
这里最主要的两个属性分别是:
1.app:headerLayout: 给NavigationView添加头部布局
2.app:menu:给NavigationView添加menu菜单布局
代码中控制NavigationView
private void initNavigationView(){ navigationView = (NavigationView) findViewById(R.id.navigationView); drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); //设置侧滑菜单选择监听事件 navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() { @Override public boolean onNavigationItemSelected(MenuItem menuItem) { menuItem.setChecked(true); //关闭抽屉侧滑菜单 drawerLayout.closeDrawers(); return true; } }); } @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == android.R.id.home){ //打开抽屉侧滑菜单 drawerLayout.openDrawer(GravityCompat.START); } return super.onOptionsItemSelected(item); }
关于NavigationView中item的字体颜色和icon选中状态颜色是去当前主题theme中的
<--正常状态下字体颜色和icon颜色-->
<item name="android:textColorPrimary">@android:color/darker_gray</item>
<--选中状态icon的颜色和字体颜色-->
<item name="colorPrimary">@color/accent_material_light</item>
也可以通过如下方法或者属性来改变这一状态:
- setItemBackgroundResource(int):给menu设置背景资源,对应的属性app:itemBackground
- setItemIconTintList(ColorStateList):给menu的icon设置颜色,对应的属性app:itemIconTint
- setItemTextColor(ColorStateList):给menu的item设置字体颜色,对应的属性app:itemTextColor