149.ViewGroup实现策划菜单

使用ViewGroup需要实现onMeasure方法,需要先实现测量才能布局画图

1.在ViewGroup中,让自己内容移动有以下几个方法:
layout(l,t,r,b);
offsetTopAndBottom(offset)和offsetLeftAndRight(offset);
scrollTo和scrollBy方法;
注意:滚动的并不是viewgroup内容本身,而是它的矩形边框 它是瞬间移动,
2.在自定义ViewGroup中一般不需要去实现onMeasure, 我们去实现系统已有的ViewGroup,比如FrameLayout, 它会帮我们区实现onMeasure方法

范例如下

package com.ldw.slide;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;

/*
 * 自定义布局
 */
public class SlideMenu extends ViewGroup {

	private View menuView, WindowView;
	private int menuWidth = 0;
	public SlideMenu(Context context) {
		super(context);
		init();
	}

	public SlideMenu(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}
	
	//布局的初始化
	private void init(){
		
	}
	
	/**
	 * 当1级的子view全部加载完调用,可以用初始化子view的引用
	 * 注意,这里无法获取子view的宽高
	 */
	@Override
	protected void onFinishInflate() {
		super.onFinishInflate();
		//获取activity_main布局中的第一个子view,layout_menu
		menuView = getChildAt(0);
		//获取activity_main布局中的第一个子view,layout_window
		WindowView = getChildAt(1);
		//menu的宽度
		menuWidth = menuView.getLayoutParams().width;
		
	}
	
	//测量的方法,参数代表系统测量SlideMenu时传入的参数
	//参数测量出的宽高能让SlideMenu充满窗体,其实是正好等于屏幕宽高
	//viewGroup需要测量所有子view的宽高
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		//测量所有子view的宽高
		
		//通过getLayoutParams方法可以获取到布局文件中指定宽高,menuView中制定了宽高
		menuView.measure(menuView.getLayoutParams().width, heightMeasureSpec);
		//直接使用SlideMenu的测量参数,因为它的宽高的布局都是充满父窗体
		WindowView.measure(widthMeasureSpec, heightMeasureSpec);
	}

	//测量完成以后需要显示,显示布局的文件
	//l: 当前子view的左边在父view的坐标系中的x坐标
	//t: 当前子view的顶边在父view的坐标系中的y坐标
	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		//menu的l就是宽度的负数
		menuView.layout(-menuView.getLayoutParams().width, 0, 0, menuView.getMeasuredHeight());
		//主窗体的宽高是屏幕的宽高
		WindowView.layout(0, 0, r, b);

	}
	
	//获取左边menu移动的距离
	private int downX;
	//触摸事件
	public boolean onTouchEvent(MotionEvent event){
		switch(event.getAction()){
		case MotionEvent.ACTION_DOWN:
			downX = (int) event.getX();
			break;
		case MotionEvent.ACTION_MOVE:
			//记录新的坐标
			int moveX = (int) event.getX();
			//往右移动10
			int detaX = (int) (event.getX() - downX);
			//根据触摸事件,获取到滚动的x的位移
			int newScrollX = getScrollX() - detaX;
			//达到了边界
			if(newScrollX<-menuWidth) newScrollX = -menuWidth;
			if(newScrollX>0)newScrollX = 0;
			//改变位置
			scrollTo(newScrollX, 0);
			//更新x距离
			downX = moveX;
			break;
		case MotionEvent.ACTION_UP:
			break;
		}
		return false;
	}

}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值