Android侧滑菜单之DrawerLayout用法详解
onconfigurationchanged最早的时候实现侧滑菜单功能大多时候需要通过github上一个叫做slidingmenu的开源通过依赖包来实现,后来谷歌在v4包中添加了drawerlayout来实现这个功能,完全可以替代slidingmenu,这里我们来学习drawerlayout的用法
一)创建drawerlayout
1)在布局文件里将布局设置为drawerlaout,而且因为是v4包中的功能,所以必须写全包名,注意第一必须先写主视图布局,然后再写抽屉里的视图,这里我们放了listview进入抽屉
<pre name="code" class="java"><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/content_frame" android:layout_width="match_parent" android:layout_height="match_parent" > </framelayout> <!-- the navigation view 左侧拉开之后的导航视图 --> <listview android:id="@+id/left_drawer" android:layout_width="240dp" android:layout_height="match_parent" android:layout_gravity="start" //从左往右滑出菜单,如果为end就是从右往左滑出菜单 android:background="#ffffcc" android:choicemode="singlechoice" android:divider="@android:color/transparent" android:dividerheight="0dp" ></listview> </android.support.v4.widget.drawerlayout>
2)在activity里将drawerlayout加载进来,并且给抽屉里的列表适配了数据,这样就将抽屉布局加载进来了。
public class mainactivity extends activity implements onitemclicklistener{ private drawerlayout mdrawerlayout; private listview mlistview; private arraylist<string> menulist;//数据 private arrayadapter<string> adapter;//适配器 // private actionbardrawertoggle mdrawertoggle; // private string mtitle; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); // mtitle=(string) gettitle(); mdrawerlayout=(drawerlayout) findviewbyid(r.id.drawer_layout); mlistview=(listview) findviewbyid(r.id.left_drawer); menulist=new arraylist<string>(); for(int i=0;i<5;i++) menulist.add("刘家威"+i); adapter=new arrayadapter<string>(this, android.r.layout.simple_list_item_1,menulist); mlistview.setadapter(adapter);
二)给抽屉里的列表添加点击事件,动态添加碎片进入主视图
1)给抽屉里的列表项添加点击事件,每点击列表项,让其在主内容视图里添加一个fragment,让这个fragment里显示点击的列表项里的内容,先写这个fragmentlayout里的布局,这里让其显示一段文本
<?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" > <textview android:id="@+id/tv" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:textsize="25sp"/> </linearlayout>
2)创建fragment,在这里重写oncreateview(),把布局加载进来,然后获取到点击项里的内容,这个是在mainactivity里通过让碎片携带参数的方法来实现
package com.example.drawerlayout; import android.app.fragment; import android.os.bundle; import android.view.layoutinflater; import android.view.view; import android.view.viewgroup; import android.widget.textview; public class contentfragment extends fragment { private textview tv; @override public view oncreateview(layoutinflater inflater, viewgroup container, bundle savedinstancestate) { view view=inflater.inflate(r.layout.fragment_content,container,false); tv=(textview) view.findviewbyid(r.id.tv); string text=getarguments().getstring("text"); //获取到传入的值 tv.settext(text); return view; } }
3)给抽屉里的列表添加点击事件,点击后会进入碎片界面,并且碎片携带了bundle类型的参数,参数的值我们传入了列表数据menulist.get(position),使用碎片的方法如下,获取碎片的实例之后再通过getfragmentmanager()获取碎片管理器,给碎片管理器开启事务,开启事务之后的碎片管理器用replace()方法将碎片的布局替换原来的主视图布局,这样一个碎片就添加进来了
最后别忘了关闭抽屉
@override public void onitemclick(adapterview<?> parent, view view, int position, long id) { //在framelayout里动态插入一个fragment fragment contentfragment=new contentfragment(); //创建碎片实例 bundle args=new bundle(); //让每个碎片都携带参数,初始化为bundle类型 args.putstring("text", menulist.get(position)); //参数put进入string类型的值,传入当前点击的菜单项的值 contentfragment.setarguments(args); //让碎片携带上参数 fragmentmanager fm=getfragmentmanager(); fm.begintransaction().replace(r.id.content_frame,contentfragment ).commit(); //开启事务,向容器内加入碎片,最后提交事务 mdrawerlayout.closedrawer(mlistview); //进入碎片界面时关闭掉抽屉的内容 }
三)监听抽屉的打开关闭事件
使用actionbardrawertoggle,最早的时候在v4包里,现在谷歌把它搬到了v7包里,所以要引入v7依赖包
在引入v7包的时候,我遇到了一个错误,support\v7\appcompat\res\values-21\themes-base.xml:error:error retrieving parent for item :no resources found that matches the given name.
这是因为v7包版本过低,解决方法是在project:properties里target=android-8改为21以上就好
当抽屉打开的时候,标题栏改为"请选择",当抽屉关闭的时候,标题栏变为原来的app标题
mtitle=(string) gettitle()
mdrawertoggle=new actionbardrawertoggle(this, mdrawerlayout, r.string.drawer_open,r.string.drawer_close){ @override public void ondraweropened(view drawerview) { super.ondraweropened(drawerview); getactionbar().settitle("请选择"); invalidateoptionsmenu();//重绘actionbar上的菜单项,执行这个方法的时候会回调onpreareoptionsmenu() } @override public void ondrawerclosed(view drawerview) { super.ondrawerclosed(drawerview); getactionbar().settitle(mtitle); invalidateoptionsmenu(); } }; mdrawerlayout.setdrawerlistener(mdrawertoggle);
因为我们改变了actionbar的内容,因此要调用invalidateoptionsmenu()会重绘actionbar上的菜单项,执行这个方法的时候会回调onpreareoptionsmenu(),所以我们可以在这里通过判断抽屉处于打开还是关闭状态,来进行一些操作,比如隐藏actionbar的菜单项。
既然要隐藏,那么前提是我们得有菜单项,这里先给actionbar添加一个搜索按钮,关于给actionbar添加按钮的办法,在关于actionbar的博客里已经讲过了,所以这里直接操作
res/values/menu/main.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context="com.example.drawerlayout.mainactivity" > <item android:id="@+id/websearch" android:icon="@drawable/action_search" android:showasaction="ifroom|withtext" android:title="websearch" /> </menu>
然后将菜单加载进来
@override public boolean oncreateoptionsmenu(menu menu) { getmenuinflater().inflate(r.menu.main, menu); return super.oncreateoptionsmenu(menu); }
顺路给这个搜索按钮设置点击事件
/*给actionbar的websearch设置点击事件*/ @override public boolean onoptionsitemselected(menuitem item) { switch (item.getitemid()) { case r.id.websearch: intent intent=new intent(); intent.setaction("android.intent.action.view"); intent.setdata(uri.parse("http://www.baidu.com")); startactivity(intent); break; default: break; } return super.onoptionsitemselected(item); }
最后在onprepareoptionsmenu()里通过drawerlayout的isopen()来判断,如果打开了就隐藏菜单项
@override public boolean onprepareoptionsmenu(menu menu) { /*在这里通过判断drawerlayout是打开还是关闭,来判断是否显示actionbar的websearch图标*/ boolean isdraweropen=mdrawerlayout.isdraweropen(mlistview); menu.finditem(r.id.websearch).setvisible(!isdraweropen); //如果drawerlayout是关闭的就显示actionbar里的websearch return super.onprepareoptionsmenu(menu); }
四)点击图标开闭抽屉
为了更加方便的使用抽屉,我们可以通过点击图标来开闭抽屉界面
1)在oncreate()里开启app icon的功能
//开启actionbar的app icon的功能 getactionbar().setdisplayhomeasupenabled(true); getactionbar().sethomebuttonenabled(true);
2)因为图标也是一个菜单项,所以点击它也是会调用onoptionsitemselected(menuitem item)
@override public boolean onoptionsitemselected(menuitem item) { //将actionbar上的图标与drawer结合起来 if(mdrawertoggle.onoptionsitemselected(item)){ return true; } ....... }
这样就实现了这个功能,但是图标还是原来的icon,现在把抽屉布局和actionbardrawertoggle同步
3)谷歌官方推荐在onpostcreate()里来同步,并且谷歌推荐写上onconfigurationchanged()
@override protected void onpostcreate(bundle savedinstancestate) { //将actionbardrawertoggle与drawerlayout同步起来 //将actionbardrawertoggle中的drawer图标设置为actionbar里的home_button的图标 mdrawertoggle.syncstate(); super.onpostcreate(savedinstancestate); } //这个方法用来监测手机状态的变化,比如横屏竖屏的切换 @override public void onconfigurationchanged(configuration newconfig) { mdrawertoggle.onconfigurationchanged(newconfig); super.onconfigurationchanged(newconfig); }
综合以上的所有内容,效果图如下
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。如果你想了解更多相关内容请查看下面相关链接
上一篇: VBS编程教程 (第3篇)
下一篇: CreateWeb.vbs 代码
推荐阅读