Android自定义ViewGroup实现侧滑菜单

自定义控件之侧滑菜单SlidingViewGroup

github地址:https://github.com/mingC0758/SlidingViewGroup

本文主要介绍实现一个侧滑菜单的过程。利用ViewGroup来实现,并且具有强扩展性,用户可以自定义主要内容视图和侧滑菜单视图,并妥善处理了父View跟子View的滑动冲突问题。

灵感来源与需求

灵感主要来自TIM的聊天信息的滑动菜单:
这里写图片描述

需求:

  1. ViewGroup允许用户放入两个视图,一个作为内容视图,一个作为菜单视图。
  2. 滑动距离或速度大于阈值时滑出菜单
  3. 在菜单视图中进行滑动时不响应菜单的点击事件

实现过程

常量定义:

/**
	 * 滑动距离占副View比值阈值,超过自动滑出
	 */
	private final float SCROLL_DISTANCE_SHREHOLD = 0.2f;

	/**
	 * 速度阈值,超过这个数自动滑出
	 */
	private final float SCROLL_SPEED_SHREHOLD = 500;

定义了一个滑动距离阈值和一个滑动速度阈值,任意一个超过了都进行滑动操作。

定义状态:

/**
	 * 状态
	 */
	private State mState = State.AT_FIRST;

	private enum State {
		AT_FIRST,  AT_SECOND
	}

AT_FIRST:在内容视图;

AT_SECOND:在菜单视图。

测量ViewGroup大小,如果ViewGroup指定了大小,则设置为指定大小,否则设置为子View中的最大值:

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		int widthSize = MeasureSpec.getSize(widthMeasureSpec);
		int heightSize = MeasureSpec.getSize(heightMeasureSpec);
		int widthMode = getMode(widthMeasureSpec);
		int heightMode = getMode(heightMeasureSpec);

		//只测量前两个子View,其他的忽视
		int childCount = getChildCount();
		if (childCount > 0) {
			//测量子View1
			measureChild(getChildAt(0), widthMeasureSpec, heightMeasureSpec);
		}

		if (childCount > 1) {
			//测量子View2,宽度限定为本容器的特定比例
			int slidingViewMS = MeasureSpec.makeMeasureSpec((int) (widthSize * mMenuWidthRadio),
					widthMode);
			measureChild(getChildAt(1), slidingViewMS, heightMeasureSpec);
		}

		//计算子View中的最高和最宽
		int maxH = 0;
		int maxW = 0;

		if (childCount > 1) {
			int h1 = getChildAt(0).getMeasuredHeight();
			int h2 = getChildAt(1).getMeasuredHeight();
			maxH = h1 > h2 ? h1 : h2;
			int w1 = getChildAt(0).getMeasuredWidth();
			int w2 = getChildAt(1).getMeasuredWidth();
			maxW = w1 > w2 ? w1 : w2;
		} else if (childCount > 0) {
			maxW = getChildAt(0).getMeasuredWidth();
			maxH = getChildAt(0).getMeasuredHeight();
		}
        //根据ViewGroup的要求来选择大小
		if (widthMode == AT_MOST && heightMode == AT_MOST) {
			setMeasuredDimension(maxW < widthSize ? maxW : widthSize,
					maxH < heightSize ? maxH : heightSize);
		} else if (widthMode == AT_MOST) {
			setMeasuredDimens
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值