onFinishInflate()、onMeasure()、onLayout()的调用顺序
2015-12-03 20:45
351 查看
package com.atguigu.view_slidemenu;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.Scroller;
/*
* 1. 如何初始显示正常?
* 1). 得到menuView
* 2). 得到menuView的宽高
* 3). 对menuView进行重新布局
* 2. 如何拖动界面?
* 2.1). 使用界面响应触控操作: 重写onTouchEvent(), 计算移动的偏移量
* 2.2). 使用view的scrollTo()进行移动
* 2.3). 限制水平移动的范围
* 3. 如何松开手指时菜单自动平滑打开/关闭
* 3.1). 处理up事件, 得到当前x的偏移量,并判断是打开/关闭
* 3.1). 实现平滑打开或关闭
*/
public class SlideMenuLayout extends FrameLayout {
private View menuView;
private int menuWidth;
private int menuHeight;
private Scroller scroller;
public SlideMenuLayout(Context context, AttributeSet attrs) {
super(context, attrs);
scroller = new Scroller(context);
}
//1). 得到menuView
@Override
protected void onFinishInflate() {
menuView = getChildAt(0);
System.out.println("SlideMenuLayout.onFinishInflate()");
}
//2). 得到menuView的宽高
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
System.out.println("SlideMenuLayout.onMeasure()");
menuWidth = menuView.getMeasuredWidth();
menuHeight = menuView.getMeasuredHeight();
}
//3). 对menuView进行重新布局
@Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
System.out.println("SlideMenuLayout.onLayout()");
super.onLayout(changed, left, top, right, bottom);
menuView.layout(-menuWidth, 0, 0, menuHeight);
}
private int lastX;
//2.1). 使用界面响应触控操作: 重写onTouchEvent(), 计算移动的偏移量
@Override
public boolean onTouchEvent(MotionEvent event) {
int eventX = (int) event.getRawX();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
lastX = eventX;
break;
case MotionEvent.ACTION_MOVE:
int dx = eventX-lastX;
int toScrollX = getScrollX()-dx;
//2.3). 限制水平移动的范围[-menuWidth, 0]
if(toScrollX<-menuWidth) {
toScrollX = -menuWidth;
} else if(toScrollX>0) {
toScrollX = 0;
}
//2.2). 使用view的scrollTo()进行移动
scrollTo(toScrollX, getScrollY());
lastX = eventX;
break;
case MotionEvent.ACTION_UP:
//3.1). 处理up事件, 得到当前x的偏移量,并判断是打开/关闭
int scrollX = getScrollX();
if(scrollX<-menuWidth/2) {
openMenu();
} else {
closeMenu();
}
break;
default:
break;
}
return true;
}
/**
* 关闭菜单 getScrollX()-->0
*/
public void closeMenu() {
scroller.startScroll(getScrollX(), getScrollY(), -getScrollX(), 0);
invalidate();
}
/**
* 打开菜单 getScrollX()--> -menuWidth
*/
public void openMenu() {
scroller.startScroll(getScrollX(), getScrollY(), -getScrollX()-menuWidth, 0);
invalidate();
}
@Override
public void computeScroll() {
super.computeScroll();
if(scroller.computeScrollOffset()) {
scrollTo(scroller.getCurrX(), scroller.getCurrY());
invalidate();
}
}
/**
* 切换状态
*/
public void switchState() {
if(getScrollX()==0) {
openMenu();
} else if(getScrollX()==-menuWidth) {
closeMenu();
}
}
}
打印的Log日志
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.Scroller;
/*
* 1. 如何初始显示正常?
* 1). 得到menuView
* 2). 得到menuView的宽高
* 3). 对menuView进行重新布局
* 2. 如何拖动界面?
* 2.1). 使用界面响应触控操作: 重写onTouchEvent(), 计算移动的偏移量
* 2.2). 使用view的scrollTo()进行移动
* 2.3). 限制水平移动的范围
* 3. 如何松开手指时菜单自动平滑打开/关闭
* 3.1). 处理up事件, 得到当前x的偏移量,并判断是打开/关闭
* 3.1). 实现平滑打开或关闭
*/
public class SlideMenuLayout extends FrameLayout {
private View menuView;
private int menuWidth;
private int menuHeight;
private Scroller scroller;
public SlideMenuLayout(Context context, AttributeSet attrs) {
super(context, attrs);
scroller = new Scroller(context);
}
//1). 得到menuView
@Override
protected void onFinishInflate() {
menuView = getChildAt(0);
System.out.println("SlideMenuLayout.onFinishInflate()");
}
//2). 得到menuView的宽高
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
System.out.println("SlideMenuLayout.onMeasure()");
menuWidth = menuView.getMeasuredWidth();
menuHeight = menuView.getMeasuredHeight();
}
//3). 对menuView进行重新布局
@Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
System.out.println("SlideMenuLayout.onLayout()");
super.onLayout(changed, left, top, right, bottom);
menuView.layout(-menuWidth, 0, 0, menuHeight);
}
private int lastX;
//2.1). 使用界面响应触控操作: 重写onTouchEvent(), 计算移动的偏移量
@Override
public boolean onTouchEvent(MotionEvent event) {
int eventX = (int) event.getRawX();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
lastX = eventX;
break;
case MotionEvent.ACTION_MOVE:
int dx = eventX-lastX;
int toScrollX = getScrollX()-dx;
//2.3). 限制水平移动的范围[-menuWidth, 0]
if(toScrollX<-menuWidth) {
toScrollX = -menuWidth;
} else if(toScrollX>0) {
toScrollX = 0;
}
//2.2). 使用view的scrollTo()进行移动
scrollTo(toScrollX, getScrollY());
lastX = eventX;
break;
case MotionEvent.ACTION_UP:
//3.1). 处理up事件, 得到当前x的偏移量,并判断是打开/关闭
int scrollX = getScrollX();
if(scrollX<-menuWidth/2) {
openMenu();
} else {
closeMenu();
}
break;
default:
break;
}
return true;
}
/**
* 关闭菜单 getScrollX()-->0
*/
public void closeMenu() {
scroller.startScroll(getScrollX(), getScrollY(), -getScrollX(), 0);
invalidate();
}
/**
* 打开菜单 getScrollX()--> -menuWidth
*/
public void openMenu() {
scroller.startScroll(getScrollX(), getScrollY(), -getScrollX()-menuWidth, 0);
invalidate();
}
@Override
public void computeScroll() {
super.computeScroll();
if(scroller.computeScrollOffset()) {
scrollTo(scroller.getCurrX(), scroller.getCurrY());
invalidate();
}
}
/**
* 切换状态
*/
public void switchState() {
if(getScrollX()==0) {
openMenu();
} else if(getScrollX()==-menuWidth) {
closeMenu();
}
}
}
打印的Log日志
相关文章推荐
- while,do while和for循环语句的用法
- BZOJ1079: [SCOI2008]着色方案
- C语言之宏
- 【bzoj1132】[POI2008] Tro
- LDA算法学习(Matlab实现)
- error occurred during initialization of vm
- HPU ACM15级周练
- JAVA生成图片验证码API
- window系统快捷键
- 第十三周学习报告
- 操作数据库类SQLHelp.cs
- window对象
- HDU 1103 Restaurant
- 0707什么是JSON+如何处理JSON字符串0
- 扣丁学堂——Activity(一)
- java并发编程学习之currentThread方法学习
- 关于liunx上面的vi编辑器的使用小总结
- 如何调试curl
- 查找——图文详解HashTree(哈希树)
- 如何对DevExpress ASPxGridView进行分组排序?