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