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 中写自己需要实现的方式. 这里定 ...
随机推荐
- 利用SharpZipLib对字符串进行压缩和解压缩
添加对ICSharpCode.SharpZipLib的引用. using ICSharpCode.SharpZipLib.BZip2; /// <summary> /// 压缩 /// & ...
- HDU 5291 Candy Distribution DP 差分 前缀和优化
Candy Distribution 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5291 Description WY has n kind of ...
- HTML导出Excel数据类型转换样式参考
mso-number-format:"0" NO Decimals mso-number-format:"0/.000" 3 Decimals mso-numb ...
- ROS知识(3)----功能包package编译的两种方式
ROS的包编译有两种方法(我知道的),一种是用rosmake,这种方法简单:另一种是用catkin_make,这种方法更方便包的管理和开发.这两种方法都是先建立工作空间workspace(类似于vs下 ...
- 用rem设置文字大小
一.px与em 用px设置文字大小是再正常不过的事情,比如 html {font-size: 12px;} 随处可见的在设置width.height使用px,这也是细致稳妥的设置方法,这样做的缺点在于 ...
- 将dll文件注入到其他进程中的一种新方法
http://www.45it.com/windowszh/201212/33946.htm http://www.hx95.cn/Article/OS/201212/65095.html 我们知道将 ...
- Druid 配置_DruidDataSource参考配置
以下是一个参考的连接池配置: <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource ...
- Linux文件目录的一点小结
转载:http://blog.chinaunix.net/uid-29171357-id-3889735.html 1. 相关指令: chgrp:改变文件所属用户组 点击(此处)折叠或打开 ...
- Run Redis On Windows
If you go to the current version and open up the bin > release folder, you'll get a ZIP file cont ...
- js隐藏表格的一行数据
1.方法 document.getElementById('customerAccount_tr').style.display="";//缴纳人名称显示 document.get ...