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蒙层下:

二.演示效果图

三.代码实现过程解析
根据上面的概述,大家应该知道大概的思路了,下面我就给出自定义侧滑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();
}
});
五.项目代码结构图

注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权
Android 打造完美的侧滑菜单/侧滑View控件的更多相关文章
- Android打造完美的刮刮乐效果控件
技术:Android+Java 概述 趁着元旦假期之际,首先在这里,我祝福大家在新的2019年都一个个的新健康,新收入,新顺利,新如意!!! 上一偏,我介绍了用Xfermode实现自定义圆角和椭圆 ...
- Android 自定义View修炼-打造完美的自定义侧滑菜单/侧滑View控件
一.概述 在App中,经常会出现侧滑菜单,侧滑滑出View等效果,虽然说Android有很多第三方开源库,但是实际上 咱们可以自己也写一个自定义的侧滑View控件,其实不难,主要涉及到以下几个要点: ...
- Android 打造炫目的圆形菜单 秒秒钟高仿建行圆形菜单
原文:Android 打造炫目的圆形菜单 秒秒钟高仿建行圆形菜单 转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/43131133, ...
- ANDROID L——Material Design详解(UI控件)
转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! Android L: Google已经确认Android L就是Android Lolli ...
- android 开发进阶 自定义控件-仿ios自动清除控件
先上图: 开发中经常需要自定义view控件或者组合控件,某些控件可能需要一些额外的配置.比如自定义一个标题栏,你可能需要根据不同尺寸的手机定制不同长度的标题栏,或者更常见的你需要配置标题栏的背景,这时 ...
- 怎样在Android实现桌面清理内存简单Widget小控件
怎样在Android实现桌面清理内存简单Widget小控件 我们常常会看到类似于360.金山手机卫士一类的软件会带一个widget小控件,显示在桌面上,上面会显示现有内存大小,然后会带一个按键功能来一 ...
- Android 自定义支持快速搜索筛选的选择控件(一)
Android 自定义支持快速搜索筛选的选择控件 项目中遇到选择控件选项过多,需要快速查找匹配的情况. 做了简单的Demo,效果图如下: 源码地址:https://github.com/whieenz ...
- 巧用Handler获取View控件信息
众所周知,在Android实际开发中,对于某些复杂多变的情况,控件的位置摆放.大小控制并非是xml类型的layout文件完全可以搞定的.此时,我们通常会使用Java代码来通过动态计算,将指定的控件摆放 ...
- 定制自己的动画 View 控件(Canvas 使用)
定制自己的动画 View 控件(Canvas 使用) 如果要定义自己的 View 控件,则需要新建一个类继承 android.view.View.然后在 onDraw 中写自己需要实现的方式. 这里定 ...
随机推荐
- Python类中self的作用
摘自论坛: self:是指向你新创建对象实例的引用,在这个地方指向你创建的Person类的实例p.当你调用Person类创建实例时,self指的就是你这个P,所以这个地方p=Person('tiany ...
- gitignore : VisualStudio.gitignore
https://github.com/github/gitignore/blob/master/VisualStudio.gitignore ## Ignore Visual Studio tempo ...
- [转].net reactor 学习系列(四)---.net reactor应用场景
前面已经学习了.net reactor一些基础知识,现在准备学习下实际的应用场景,只是简单的保护和许可证发放场景.如果想应用更高级的场景比如自动化程序许可证的发放及自定义客户端的过期提示等等就需要自己 ...
- PHP中getenv()和$_SERVER的区别
PHP中getenv()和$_SERVER的用法区别: getenv 取得系统的环境变量,环境变量的格式为name=value. 语法: string getenv(string varname); ...
- Linq 分组(group by)求和(sum)并且按照分隔符(join)分割列数据
转载:http://www.cnblogs.com/zq281660880/archive/2012/09/26/2704836.html 今天在使用linq处理一下需求时碰到一点小问题,特此记录. ...
- 代码规范审查 – Sonar分析项目
Sonar搭建成功之后,就可以通过简单的CMD指令进行项目分析,此篇主要介绍使用Sonar来分析.net项目. 扫描步骤: a. 打开CMD,切换到指定的项目根目录,和.sln同级目录即可(此处 ...
- 数学图形(2.8)Viviani曲线
维维亚尼(Viviani , Vincenzo)意大利数学家.1622年4月5日生于托斯卡纳大区佛罗伦萨:1703年9月22日卒于佛罗伦萨. 这是一个圆柱与一个球相交而生成的曲线. #http://w ...
- nmap常用扫描命令
NMap,也就是Network Mapper,是Linux下的网络扫描和嗅探工具包. nmap是在网络安全渗透测试中经常会用到的强大的扫描器.功能之强大,不言而喻.下面介绍一下它的几种扫描命令.具体的 ...
- 文本相似性计算总结(余弦定理,simhash)及代码
最近在工作中要处理好多文本文档,要求找出和每个文档的相识的文档.通过查找资料总结如下几个计算方法: 1.余弦相似性 我举一个例子来说明,什么是"余弦相似性". 为了简单起见,我们先 ...
- EasyUI-EasyUI框架入门学习
前言 新项目的开发前端技术打算采用EasyUI框架(基于EasyUI较为丰富的UI组件库),项目组长将前端EasyUI这块的任务分配给了我.在进行开发之前,需要我这菜鸟对EasyUI框架进行一些基础的 ...