onFinishInflate()、onMeasure()、onLayout()的调用顺序

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日志


你可能感兴趣的:(安卓)