Android控件View打造完美的自定义侧滑菜单
一、概述
在app中,经常会出现侧滑菜单,侧滑滑出view等效果,虽然说android有很多第三方开源库,但是实际上咱们可以自己也写一个自定义的侧滑view控件,其实不难,主要涉及到以下几个要点:
1.对android中window类中的decorview有所了解
2.对scroller类实现平滑移动效果
3.自定义viewgroup的实现
首先来看看效果图吧:
下面现在就来说说这里咱们实现侧滑view的基本思路吧,这里我采用的是自定义一个继承于relativelayout的控件叫做xcslideview类吧。
首先从布局文件中inflater出来一个menuview,然后通过addview的方法,将该侧滑view添加到自定义的控件view中怎么让xcslideview 这个侧滑view 隐藏到屏幕之外呢?很简单通过scrollto方法,移动一个屏幕宽度的距离即可,这里以左侧滑出为例吧,只需要这样 xcslideview.this.scrollto(mscreenwidth, 0);mscreenwidth是屏幕宽度。下面还要处理的就是底下的半透明黑色的蒙层效果,这个其实就是一个view,然后设置半透明效果。这个当然简单了,关键是咱们让他显示在咱们的自定义侧滑view的下面呢,这里咱们先给出decorview的简单分析,方便下面介绍添加半透明view蒙层下:
下面是对上面这张图的解释:
1、decorview为整个window界面的最顶层view。
2、decorview只有一个子元素为linearlayout。代表整个window界面,包含通知栏,标题栏,内容显示栏三块区域。
3、linearlayout里有两个framelayout子元素。
(20)为标题栏显示界面。只有一个textview显示应用的名称。也可以自定义标题栏,载入后的自定义标题栏view将加入framelayout中。
(21)为内容栏显示界面。就是setcontentview()方法载入的布局界面,加入其中。
有了上面的decorview知识背景,现在就来说说 怎么添加蒙层view和将自定义侧滑view添加到activity的decorview中,首先把蒙层view添加到
(31)customview中去,然后将自定义侧滑view添加到 (21)framelayout中去,至于为什么要这样,是因为考虑到自定义侧滑view不一定是宽度为屏幕宽度,所以才这么做,而且也方面处理有无标题栏,有无采用沉浸式状态栏设计等情况。
二、自定义侧滑view的实现
根据上面的概述,大家应该知道大概的思路了,下面我就给出自定义侧滑view类的核心代码:
1、自定义侧滑view用到的变量:
//侧滑方向-从哪侧滑出 public static enum positon { left, right } private context mcontext; private activity mactivity; private scroller mscroller = null; //侧滑菜单布局view private view mmenuview; //底部蒙层view private view mmaskview; private int mmenuwidth = 0; //屏幕宽度 private int mscreenwidth = 0; //是否在滑动中 private boolean mismoving = false; //显示登录界面与否 private boolean mshow = false; //滑动动画时间 private int mduration = 600; //缺省侧滑方向为左 private positon mpositon = positon.left;
2、初始化创建自定义侧滑view:
** * 创建侧滑菜单view */ public static xcslideview create(activity activity) { xcslideview view = new xcslideview(activity); return view; } /** * 创建侧滑菜单view */ public static xcslideview create(activity activity, positon positon) { xcslideview view = new xcslideview(activity); view.mpositon = positon; return view; }
3、创建半透明蒙层view,并添加到contentview中去
/** * 创建 蒙层view并添加到contentview中 */ private void attachtocontentview(activity activity, positon positon) { mpositon = positon; viewgroup contentframelayout = (viewgroup) activity.findviewbyid(android.r.id.content); viewgroup contentview = ((viewgroup) contentframelayout.getchildat(0)); mmaskview = new view(activity); mmaskview.setbackgroundcolor(mcontext.getresources().getcolor(r.color.mask_color)); contentview.addview(mmaskview, contentview.getlayoutparams()); mmaskview.setvisibility(view.gone); mmaskview.setclickable(true); mmaskview.setonclicklistener(new onclicklistener() { @override public void onclick(view view) { if (isshow()) { dismiss(); } } }); }
4、设置侧滑菜单view,并添加到dectorview->linearlayout->内容显示区域view(framelayout)中
/** * 设置侧滑菜单view,并添加到dectorview->linearlayout->内容显示区域view中 */ public void setmenuview(activity activity, view view) { mactivity = activity; mmenuview = view; layoutparams params = new layoutparams(layoutparams.match_parent, layoutparams.match_parent); addview(mmenuview, params); mmenuview.post(new runnable() { @override public void run() { // todo auto-generated method stub mmenuwidth = mmenuview.getwidth(); switch (mpositon) { case left: xcslideview.this.scrollto(mscreenwidth, 0); break; case right: xcslideview.this.scrollto(-mscreenwidth, 0); break; } } }); viewgroup contentframelayout = (viewgroup) activity.findviewbyid(android.r.id.content); viewgroup contentview = contentframelayout; contentview.addview(this); framelayout.layoutparams layoutparams = (framelayout.layoutparams) this.getlayoutparams(); switch (mpositon) { case left: layoutparams.gravity = gravity.left; layoutparams.leftmargin = 0; break; case right: layoutparams.gravity = gravity.right; layoutparams.rightmargin = 0; break; } textview titleframelayout = (textview) activity.findviewbyid(android.r.id.title); if( titleframelayout != null){ layoutparams.topmargin = densityutil.getstatusbarheight(mcontext); } int flags = mactivity.getwindow().getattributes().flags; int flag = (flags & windowmanager.layoutparams.flag_translucent_status); if(flag == windowmanager.layoutparams.flag_translucent_status){ //说明状态栏使用沉浸式 layoutparams.topmargin = densityutil.getstatusbarheight(mcontext); } this.setlayoutparams(layoutparams); }
5、处理自定义侧滑view的侧滑滑动和隐藏效果:
/** * 显示侧滑菜单view */ public void show(){ if(isshow() && !mismoving) return; switch (mpositon) { case left: startscroll(mmenuwidth, -mmenuwidth, mduration); break; case right: startscroll(-mmenuwidth, mmenuwidth, mduration); break; } switchmaskview(true); mshow = true; } /** * 蒙层显示开关 */ private void switchmaskview(boolean bshow){ if(bshow){ mmaskview.setvisibility(view.visible); animation animation = new alphaanimation(0.0f, 1.0f); animation.setduration(mduration); mmaskview.startanimation(animation); }else{ mmaskview.setvisibility(view.gone); } } /** * 关闭侧滑菜单view */ public void dismiss() { // todo auto-generated method stub if(!isshow() && !mismoving) return; switch (mpositon) { case left: startscroll(xcslideview.this.getscrollx(), mmenuwidth, mduration); break; case right: startscroll(xcslideview.this.getscrollx(), -mmenuwidth, mduration); break; } switchmaskview(false); mshow = false; } public boolean isshow(){ return mshow; } @override public void computescroll() { // todo auto-generated method stub if (mscroller.computescrolloffset()) { scrollto(mscroller.getcurrx(), mscroller.getcurry()); // 更新界面 postinvalidate(); mismoving = true; } else { mismoving = false; } super.computescroll(); } /** * 拖动移动 */ public void startscroll(int startx, int dx,int duration){ mismoving = true; mscroller.startscroll(startx,0,dx,0,duration); invalidate(); }
三、如何使用该自定义侧滑view控件
使用起来,比较简单,通过create方法创建一个侧滑view,然后通过setmenuview方法设置一个侧滑view进去,有需要设置宽度的话, 通过setmenuwidth方法来设置即可,最后用show()方法滑出来就可以啦,使用起来是不是很方便?
private xcslideview mslideviewleft; //屏幕宽度 private int mscreenwidth = 0; view menuviewleft = layoutinflater.from(mcontext).inflate(r.layout.layout_slideview,null); mslideviewleft = xcslideview.create(this, xcslideview.positon.left); mslideviewleft.setmenuview(mainactivity.this, menuviewleft); mslideviewleft.setmenuwidth(mscreenwidth * 7 / 9); button left = (button)findviewbyid(r.id.btn_left); left.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { // todo auto-generated method stub if (!mslideviewleft.isshow()) mslideviewleft.show(); } });
四、源码下载
下载:侧滑菜单
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。