android 自定义侧拉,Android控件View打造完美的自定义侧滑菜单

一、概述

在App中,经常会出现侧滑菜单,侧滑滑出View等效果,虽然说Android有很多第三方开源库,但是实际上咱们可以自己也写一个自定义的侧滑View控件,其实不难,主要涉及到以下几个要点:

1.对Android中Window类中的DecorView有所了解

2.对Scroller类实现平滑移动效果

3.自定义ViewGroup的实现

首先来看看效果图吧:

e2fcaa4ee854991ee82a928999c7e64d.gif

53aa0fee4113d65f0ab60d22cdf48717.png   

e3c71c13ff86aa096d6780913a31cd91.png

下面现在就来说说这里咱们实现侧滑View的基本思路吧,这里我采用的是自定义一个继承于RelativeLayout的控件叫做XCSlideView类吧。

首先从布局文件中inflater出来一个menuView,然后通过addView的方法,将该侧滑View添加到自定义的控件View中怎么让XCSlideView 这个侧滑View 隐藏到屏幕之外呢?很简单通过ScrollTo方法,移动一个屏幕宽度的距离即可,这里以左侧滑出为例吧,只需要这样 XCSlideView.this.scrollTo(mScreenWidth, 0);mScreenWidth是屏幕宽度。下面还要处理的就是底下的半透明黑色的蒙层效果,这个其实就是一个View,然后设置半透明效果。这个当然简单了,关键是咱们让他显示在咱们的自定义侧滑View的下面呢,这里咱们先给出DecorView的简单分析,方便下面介绍添加半透明View蒙层下:

514e9eac2d3023cf0f8c1ecbdf7ff86d.png

下面是对上面这张图的解释:

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

}

});

四、源码下载

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值