一.概述
在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蒙层下:
二.演示效果图
三.代码实现过程解析
根据上面的概述,大家应该知道大概的思路了,下面我就给出自定义侧滑View类的核心代码:
1、自定义侧滑View用到的变量://侧滑方向-从哪侧滑出
publicstaticenumPositon{
LEFT,RIGHT
}
privateContextmContext;
privateActivitymActivity;
privateScrollermScroller=null;
//侧滑菜单布局View
privateViewmMenuView;
//底部蒙层View
privateViewmMaskView;
privateintmMenuWidth=0;
//屏幕宽度
privateintmScreenWidth=0;
//是否在滑动中
privatebooleanmIsMoving=false;
//显示登录界面与否
privatebooleanmShow=false;
//滑动动画时间
privateintmDuration=600;
//缺省侧滑方向为左
privatePositonmPositon=Positon.LEFT;
2、初始化创建自定义侧滑View:**
*创建侧滑菜单View
*/
publicstaticXCSlideViewcreate(Activityactivity){
XCSlideViewview=newXCSlideView(activity);
returnview;
}
/**
*创建侧滑菜单View
*/
publicstaticXCSlideViewcreate(Activityactivity,Positonpositon){
XCSlideViewview=newXCSlideView(activity);
view.mPositon=positon;
returnview;
}
3、创建半透明蒙层View,并添加到contentView中去/**
*创建蒙层View并添加到contentView中
*/
privatevoidattachToContentView(Activityactivity,Positonpositon){
mPositon=positon;
ViewGroupcontentFrameLayout=(ViewGroup)activity.findViewById(android.R.id.content);
ViewGroupcontentView=((ViewGroup)contentFrameLayout.getChildAt(0));
mMaskView=newView(activity);
mMaskView.setBackgroundColor(mContext.getResources().getColor(R.color.mask_color));
contentView.addView(mMaskView,contentView.getLayoutParams());
mMaskView.setVisibility(View.GONE);
mMaskView.setClickable(true);
mMaskView.setOnClickListener(newOnClickListener(){
@Override
publicvoidonClick(Viewview){
if(isShow()){
dismiss();
}
}
});
}
4、设置侧滑菜单View,并添加到DectorView->LinearLayout->内容显示区域View(FrameLayout)中/**
*设置侧滑菜单View,并添加到DectorView->LinearLayout->内容显示区域View中
*/
publicvoidsetMenuView(Activityactivity,Viewview){
mActivity=activity;
mMenuView=view;
LayoutParamsparams=newLayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);
addView(mMenuView,params);
mMenuView.post(newRunnable(){
@Override
publicvoidrun(){
//TODOAuto-generatedmethodstub
mMenuWidth=mMenuView.getWidth();
switch(mPositon){
caseLEFT:
XCSlideView.this.scrollTo(mScreenWidth,0);
break;
caseRIGHT:
XCSlideView.this.scrollTo(-mScreenWidth,0);
break;
}
}
});
ViewGroupcontentFrameLayout=(ViewGroup)activity.findViewById(android.R.id.content);
ViewGroupcontentView=contentFrameLayout;
contentView.addView(this);
FrameLayout.LayoutParamslayoutParams=(FrameLayout.LayoutParams)this.getLayoutParams();
switch(mPositon){
caseLEFT:
layoutParams.gravity=Gravity.LEFT;
layoutParams.leftMargin=0;
break;
caseRIGHT:
layoutParams.gravity=Gravity.RIGHT;
layoutParams.rightMargin=0;
break;
}
TextViewtitleFrameLayout=(TextView)activity.findViewById(android.R.id.title);
if(titleFrameLayout!=null){
layoutParams.topMargin=DensityUtil.getStatusBarHeight(mContext);
}
intflags=mActivity.getWindow().getAttributes().flags;
intflag=(flags&WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
if(flag==WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS){
//说明状态栏使用沉浸式
layoutParams.topMargin=DensityUtil.getStatusBarHeight(mContext);
}
this.setLayoutParams(layoutParams);
}
5、处理自定义侧滑View的侧滑滑动和隐藏效果:/**
*显示侧滑菜单View
*/
publicvoidshow(){
if(isShow()&&!mIsMoving)
return;
switch(mPositon){
caseLEFT:
startScroll(mMenuWidth,-mMenuWidth,mDuration);
break;
caseRIGHT:
startScroll(-mMenuWidth,mMenuWidth,mDuration);
break;
}
switchMaskView(true);
mShow=true;
}
/**
*蒙层显示开关
*/
privatevoidswitchMaskView(booleanbShow){
if(bShow){
mMaskView.setVisibility(View.VISIBLE);
Animationanimation=newAlphaAnimation(0.0f,1.0f);
animation.setDuration(mDuration);
mMaskView.startAnimation(animation);
}else{
mMaskView.setVisibility(View.GONE);
}
}
/**
*关闭侧滑菜单View
*/
publicvoiddismiss(){
//TODOAuto-generatedmethodstub
if(!isShow()&&!mIsMoving)
return;
switch(mPositon){
caseLEFT:
startScroll(XCSlideView.this.getScrollX(),mMenuWidth,mDuration);
break;
caseRIGHT:
startScroll(XCSlideView.this.getScrollX(),-mMenuWidth,mDuration);
break;
}
switchMaskView(false);
mShow=false;
}
publicbooleanisShow(){
returnmShow;
}
@Override
publicvoidcomputeScroll(){
//TODOAuto-generatedmethodstub
if(puteScrollOffset()){
scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
//更新界面
postInvalidate();
mIsMoving=true;
}else{
mIsMoving=false;
}
puteScroll();
}
/**
*拖动移动
*/
publicvoidstartScroll(intstartX,intdx,intduration){
mIsMoving=true;
mScroller.startScroll(startX,0,dx,0,duration);
invalidate();
}
四.如何使用该自定义侧滑View控件
使用起来,比较简单,通过create方法创建一个侧滑VIew,然后通过setMenuView方法设置一个侧滑View进去,有需要设置
宽度的话, 通过setMenuWidth方法来设置即可,最后用show()方法滑出来就可以啦,使用起来是不是很方便?privateXCSlideViewmSlideViewLeft;
//屏幕宽度
privateintmScreenWidth=0;
ViewmenuViewLeft=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);
Buttonleft=(Button)findViewById(R.id.btn_left);
left.setOnClickListener(newView.OnClickListener(){
@Override
publicvoidonClick(Viewv){
//TODOAuto-generatedmethodstub
if(!mSlideViewLeft.isShow())
mSlideViewLeft.show();
}
});
五.项目代码结构图