Android控件View打造完美的自定义侧滑菜单
发布时间 - 2026-01-10 23:10:50 点击率:次一、概述

在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();
}
});
四、源码下载
下载:侧滑菜单
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# Android
# View
# 侧滑菜单
# Android编程之下拉菜单Spinner控件用法示例
# Android自定义控件实现底部菜单(下)
# Android自定义控件实现底部菜单(上)
# Android 中 SwipeLayout一个展示条目底层菜单的侧滑控件源码解析
# Android自定义控件案例汇总1(菜单、popupwindow、viewpager)
# Android自定义控件简单实现侧滑菜单效果
# Android自定义控件之仿优酷菜单
# Android使用自定义控件HorizontalScrollView打造史上最简单的侧滑菜单
# Android控件之菜单的创建方式
# 自定义
# 标题栏
# 中去
# 滑出
# 只有一个
# 就来
# 有无
# 的是
# 状态栏
# 几个
# 我就
# 是因为
# 让他
# 有很多
# 很简单
# 来看看
# 考虑到
# 只需要
# 为例
# 拖动
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
JS经典正则表达式笔试题汇总
Laravel如何正确地在控制器和模型之间分配逻辑_Laravel代码职责分离与架构建议
如何快速建站并高效导出源代码?
魔毅自助建站系统:模板定制与SEO优化一键生成指南
移动端手机网站制作软件,掌上时代,移动端网站的谷歌SEO该如何做?
太平洋网站制作公司,网络用语太平洋是什么意思?
Edge浏览器提示“由你的组织管理”怎么解决_去除浏览器托管提示【修复】
Laravel全局作用域是什么_Laravel Eloquent Global Scopes应用指南
JS中使用new Date(str)创建时间对象不兼容firefox和ie的解决方法(两种)
韩国代理服务器如何选?解析IP设置技巧与跨境访问优化指南
网站优化排名时,需要考虑哪些问题呢?
Laravel如何优化应用性能?(缓存和优化命令)
Laravel Octane如何提升性能_使用Laravel Octane加速你的应用
Laravel PHP版本要求一览_Laravel各版本环境要求对照
安克发布新款氮化镓充电宝:体积缩小 30%,支持 200W 输出
今日头条AI怎样推荐抢票工具_今日头条AI抢票工具推荐算法与筛选【技巧】
如何快速重置建站主机并恢复默认配置?
html5的keygen标签为什么废弃_替代方案说明【解答】
如何有效防御Web建站篡改攻击?
如何在Ubuntu系统下快速搭建WordPress个人网站?
Laravel如何实现URL美化Slug功能_Laravel使用eloquent-sluggable生成别名【方法】
Laravel用户认证怎么做_Laravel Breeze脚手架快速实现登录注册功能
齐河建站公司:营销型网站建设与SEO优化双核驱动策略
进行网站优化必须要坚持的四大原则
大连网站制作费用,大连新青年网站,五年四班里的视频怎样下载啊?
Laravel表单请求验证类怎么用_Laravel Form Request分离验证逻辑教程
通义万相免费版怎么用_通义万相免费版使用方法详细指南【教程】
利用 Google AI 进行 YouTube 视频 SEO 描述优化
Laravel如何使用Laravel Vite编译前端_Laravel10以上版本前端静态资源管理【教程】
Bootstrap整体框架之JavaScript插件架构
如何快速生成ASP一键建站模板并优化安全性?
如何获取免费开源的自助建站系统源码?
JS实现鼠标移上去显示图片或微信二维码
详解CentOS6.5 安装 MySQL5.1.71的方法
微信小程序 scroll-view组件实现列表页实例代码
重庆市网站制作公司,重庆招聘网站哪个好?
Laravel怎么生成URL_Laravel路由命名与URL生成函数详解
Java垃圾回收器的方法和原理总结
英语简历制作免费网站推荐,如何将简历翻译成英文?
php json中文编码为null的解决办法
如何用低价快速搭建高质量网站?
香港服务器网站生成指南:免费资源整合与高速稳定配置方案
JavaScript 输出显示内容(document.write、alert、innerHTML、console.log)
Python进程池调度策略_任务分发说明【指导】
laravel怎么为应用开启和关闭维护模式_laravel应用维护模式开启与关闭方法
如何快速打造个性化非模板自助建站?
制作ppt免费网站有哪些,有哪些比较好的ppt模板下载网站?
Win11怎么关闭资讯和兴趣_Windows11任务栏设置隐藏小组件
edge浏览器无法安装扩展 edge浏览器插件安装失败【解决方法】
php静态变量怎么调试_php静态变量作用域调试技巧【解答】
下一篇:laravel队列能做什么
下一篇:laravel队列能做什么

