侧滑菜单


public class MainActivity extends Activity {


@Override

protected void onCreate(Bundle savedInstanceState) {

requestWindowFeature(Window.FEATURE_NO_TITLE);// 隐藏系统的标题栏

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

final SlidingMenu slidingMenu = (SlidingMenu) findViewById(R.id.sliding_menu);

findViewById(R.id.btn_show_menu).setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

slidingMenu.toggle();

}

});

}


public void onClickMenu(View v) {

TextView menuTextView = (TextView) v;

Toast.makeText(this, menuTextView.getText(), Toast.LENGTH_SHORT).show();

}


}







public class SlidingMenu extends ViewGroup {


private int menuViewWidth;

private View menuView;

private View mainView;

private float downX;

/** 是否有移动操作 */

private boolean hasMove;

private float distanceX;

/** 菜单当前移动到的位置 */

private float currentX;

/** 用于模拟滚动数据的类 */

private Scroller scroller;

private float downY;


public SlidingMenu(Context context, AttributeSet attrs) {

super(context, attrs);

scroller = new Scroller(context);

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

menuView = getChildAt(0);

mainView = getChildAt(1);

// 测量菜单

menuViewWidth = menuView.getLayoutParams().width;

menuView.measure(menuViewWidth, heightMeasureSpec);

// 测量主界面

mainView.measure(widthMeasureSpec, heightMeasureSpec);

}


@Override

protected void onLayout(boolean changed, int l, int t, int r, int b) {

// 对SlidingMenu里面的子控件进行排版

menuView.layout(l - 240, t, l, b);

mainView.layout(l, t, r, b);

}

@Override

public boolean onTouchEvent(MotionEvent event) {

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

downX = event.getX();

break;

case MotionEvent.ACTION_MOVE:

hasMove = true;

distanceX = currentX + event.getX() - downX;

// 预防超出范围

if (distanceX < 0) {

distanceX = 0;

} else if (distanceX > menuViewWidth) {

distanceX = menuViewWidth;

}

scrollTo(distanceX);

break;

case MotionEvent.ACTION_UP:

if (hasMove) {

hasMove = false;

// 如果擡起手的时候,移动的距离小于菜单宽/2,则把菜单完全隐藏

if (distanceX < menuViewWidth / 2) {

scrollTo(0);

currentX = 0;// 要移动到的目标位置

} else {

// 完全显示

scrollTo(menuViewWidth);

currentX = menuViewWidth;// 要移动到的目标位置

}

startScroll((int) distanceX, (int) currentX);

}

break;


default:

break;

}

return true;

}

@Override

public boolean dispatchTouchEvent(MotionEvent ev) {

// TODO Auto-generated method stub

return super.dispatchTouchEvent(ev);

}

@Override

public boolean onInterceptTouchEvent(MotionEvent ev) {

switch (ev.getAction()) {

case MotionEvent.ACTION_DOWN:

downX = ev.getX();

downY = ev.getY();

break;

case MotionEvent.ACTION_MOVE:

float distanceX = ev.getX() - downX;

float distanceY = ev.getY() - downY;

if (Math.abs(distanceX) > Math.abs(distanceY)) {

// 如果水平方向移动距离比y方向移动距离大,则认为是水平移动,把touch拦截

return true;

}

break;


default:

break;

}

return super.onInterceptTouchEvent(ev);

}

/** 打开菜单或者关闭菜单 */

public void toggle() {

int startX;

int destX;

// 如果滑动距离 == 0,说明菜单原来是隐藏的,需要显示出来

if (getMyScrollX() == 0) {

startX = 0;

destX = menuViewWidth;

} else {

// 隐藏

startX = menuViewWidth;

destX = 0;

}

currentX = destX;

startScroll(startX, destX);

}


/**

* @param startX 开始移动的x位置

* @param destX 要移动到的目标位置

*/

private void startScroll(int startX, int destX) {

int dx = destX - startX; // 移动的距离

int startY = 0;

int dy = 0;

int maxDuration = 1000;

float maxMoveDistanceX = menuViewWidth;

float scale = maxDuration / maxMoveDistanceX;// 最后要算什么类型,则这个类型的数据应该做为被除数

int duration = (int) (Math.abs(dx) * scale);

scroller.startScroll(startX, startY, dx, dy, duration);

invalidate();// 通知系统去刷新View,内部会调用onDraw

}

@Override

public void computeScroll() {

if (scroller.computeScrollOffset()) {// 判断数据是否模拟结束了,如果没结束返回true

int currX = scroller.getCurrX();

scrollTo(currX);

invalidate();// 通知系统去刷新View,内部会调用onDraw

}

}

/**

* 封装系统的方法,是为了传正数的时候往右移动,传负的时候往左移动

* @param x

*/

public void scrollTo(float x) {

super.scrollTo(-(int) x, 0);

}

/**

* @return

*/

public int getMyScrollX() {

return -super.getScrollX();

}


}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章