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(); } });

四、源码下载

下载:侧滑菜单

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

时间: 2024-09-04 10:29:06

Android控件View打造完美的自定义侧滑菜单的相关文章

Android 自定义View修炼-打造完美的自定义侧滑菜单/侧滑View控件(转)

一.概述 在App中,经常会出现侧滑菜单,侧滑滑出View等效果,虽然说Android有很多第三方开源库,但是实际上 咱们可以自己也写一个自定义的侧滑View控件,其实不难,主要涉及到以下几个要点: 1.对Android中Window类中的DecorView有所了解 2.对Scroller类实现平滑移动效果 3.自定义ViewGroup的实现 首先来看看效果图吧:      下面现在就来说说这里咱们实现侧滑View的基本思路吧,这里我采用的是自定义一个继承于RelativeLayout的控件叫做

Android控件之RatingBar自定义星级评分样式_Android

一.RatingBar简单介绍 RatingBar是基于SeekBar(拖动条)和ProgressBar(状态条)的扩展,用星形来显示等级评定,在使用默认RatingBar时,用户可以通过触摸/拖动/按键(比如遥控器)来设置评分, RatingBar自带有两种模式 ,一个小风格 ratingBarStyleSmall,大风格为ratingBarStyleIndicator,大的只适合做指示,不适用与用户交互. 效果图展示: 二.实例 1.布局文件 <?xml version="1.0&qu

Android控件之RatingBar自定义星级评分样式

一.RatingBar简单介绍 RatingBar是基于SeekBar(拖动条)和ProgressBar(状态条)的扩展,用星形来显示等级评定,在使用默认RatingBar时,用户可以通过触摸/拖动/按键(比如遥控器)来设置评分, RatingBar自带有两种模式 ,一个小风格 ratingBarStyleSmall,大风格为ratingBarStyleIndicator,大的只适合做指示,不适用与用户交互. 效果图展示: 二.实例 1.布局文件 <?xml version="1.0&qu

Android群英传笔记——第三章:Android控件架构与自定义控件讲解

Android群英传笔记--第三章:Android控件架构与自定义控件讲解 真的很久没有更新博客了,三四天了吧,搬家干嘛的,心累,事件又很紧,抽时间把第三章大致的看完了,当然,我还是有一点View的基础的,可以先看下我之前写的几篇基础的View博客 Android绘图机制(一)--自定义View的基础属性和方法 Android绘图机制(二)--自定义View绘制形, 圆形, 三角形, 扇形, 椭圆, 曲线,文字和图片的坐标讲解 Android绘图机制(三)--自定义View的三种实现方式以及实战

Android控件之Gallery用法实例分析_Android

本文实例讲述了Android控件之Gallery用法.分享给大家供大家参考.具体如下: Gallery组件主要用于横向显示图像列表,不过按常规做法.Gallery组件只能有限地显示指定的图像.也就是说,如果为Gallery组件指定了10张图像,那么当Gallery组件显示到第10张时,就不会再继续显示了.这虽然在大多数时候没有什么关系,但在某些情况下,我们希望图像显示到最后一张时再重第1张开始显示,也就是循环显示.要实现这种风格的Gallery组件,就需要对Gallery的Adapter对象进行

Android控件之ListView用法实例详解_Android

本文实例讲述了Android控件之ListView用法.分享给大家供大家参考.具体如下: 示例一: 在android开发中ListView是比较常用的组件,它以列表的形式展示具体内容,并且能够根据数据的长度自适应显示. main.xml布局文件: <?xml version="1.0" encoding="utf-8"?> <LinearLayout android:id="@+id/LinearLayout01" androi

Android控件系列之Button以及Android监听器使用介绍_Android

学习目的: 1.掌握在Android中如何建立Button 2.掌握Button的常用属性 3.掌握Button按钮的点击事件(监听器) Button是各种UI中最常用的控件之一,它同样也是Android开发中最受欢迎的控件之一,用户可以通过触摸它来触发一系列事件,要知道一个没有点击事件的Button是没有任何意义的,因为使用者的固定思维是见到它就想去点! 先看下Android中普通Button的样子: 以及点中Button后的样子: 我在Android控件系列之XML静态资源中已经强调了布局和

Android控件之ListView用法实例详解

本文实例讲述了Android控件之ListView用法.分享给大家供大家参考.具体如下: 示例一: 在android开发中ListView是比较常用的组件,它以列表的形式展示具体内容,并且能够根据数据的长度自适应显示. main.xml布局文件: <?xml version="1.0" encoding="utf-8"?> <LinearLayout android:id="@+id/LinearLayout01" androi

Android控件之Gallery用法实例分析

本文实例讲述了Android控件之Gallery用法.分享给大家供大家参考.具体如下: Gallery组件主要用于横向显示图像列表,不过按常规做法.Gallery组件只能有限地显示指定的图像.也就是说,如果为Gallery组件指定了10张图像,那么当Gallery组件显示到第10张时,就不会再继续显示了.这虽然在大多数时候没有什么关系,但在某些情况下,我们希望图像显示到最后一张时再重第1张开始显示,也就是循环显示.要实现这种风格的Gallery组件,就需要对Gallery的Adapter对象进行