側滑菜單


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();

}


}


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