1、SlidingMenuView类


package com.zhuixingba.view;import com.zhuixingba.main.R;import android.content.Context;import android.graphics.Canvas;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.VelocityTracker;import android.view.View;import android.view.ViewConfiguration;import android.view.ViewGroup;import android.view.ViewParent;import android.widget.Scroller;/** * EffectSpace *  * @author lance *  */public class SlidingMenuView extends ViewGroup {private static String LOG_TAG = "SlidingMenuView";private static final int INVALID_SCREEN = -1;private static final int SNAP_VELOCITY = 1000;private int mDefaultScreen = 1;private int mCurrentScreen;private int mNextScreen = INVALID_SCREEN;private Scroller mScroller;private VelocityTracker mVelocityTracker;private float mLastMotionX;private float mLastMotionY;private final static int TOUCH_STATE_REST = 0;private final static int TOUCH_STATE_SCROLLING = 1;public int mTouchState = TOUCH_STATE_REST;private boolean mAllowLongPress;private boolean mLocked;private int mTouchSlop;public int totalWidth = 0;private CloseAnimation closeAnimation;public SlidingMenuView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public SlidingMenuView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);initWorkspace();postDelayed(new Runnable() {@Overridepublic void run() {scrollTo(findViewById(R.id.main_left_menu).getWidth(), 0);}}, 50);}private void initWorkspace() {mScroller = new Scroller(getContext());mCurrentScreen = mDefaultScreen;mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();}boolean isDefaultScreenShowing() {return mCurrentScreen == mDefaultScreen;}public int getCurrentScreen() {return mCurrentScreen;}public void setCurrentScreen(int currentScreen) {mCurrentScreen = Math.max(0, Math.min(currentScreen, getChildCount() - 1));invalidate();}void showDefaultScreen() {setCurrentScreen(mDefaultScreen);}@Overridepublic void computeScroll() {if (mScroller.computeScrollOffset()) {scrollTo(mScroller.getCurrX(), mScroller.getCurrY());} else if (mNextScreen != INVALID_SCREEN) {mCurrentScreen = Math.max(0, Math.min(mNextScreen, getChildCount() - 1));mNextScreen = INVALID_SCREEN;clearChildrenCache();}if (closeAnimation != null) {closeAnimation.closeMenuAnimation();}}@Overridepublic void scrollTo(int x, int y) {super.scrollTo(x, y);postInvalidate();}@Overrideprotected void dispatchDraw(Canvas canvas) {final int scrollX = getScrollX();super.dispatchDraw(canvas);canvas.translate(scrollX, 0);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);measureViews(widthMeasureSpec, heightMeasureSpec);}public void measureViews(int widthMeasureSpec, int heightMeasureSpec) {View v1 = findViewById(R.id.main_left_menu);v1.measure(v1.getLayoutParams().width + v1.getLeft() + v1.getRight(), heightMeasureSpec);View v2 = findViewById(R.id.main_body);v2.measure(widthMeasureSpec, heightMeasureSpec);}@Overrideprotected void onLayout(boolean changed, int left, int top, int right, int bottom) {int childLeft = 0;final int count = getChildCount();for (int i = 0; i < count; i++) {final View child = getChildAt(i);if (child.getVisibility() != View.GONE) {final int childWidth = child.getMeasuredWidth();child.layout(childLeft, 0, childLeft + childWidth, child.getMeasuredHeight());childLeft += childWidth;}}totalWidth = childLeft;}@Overridepublic boolean dispatchUnhandledMove(View focused, int direction) {if (direction == View.FOCUS_LEFT) {if (getCurrentScreen() > 0) {snapToScreen(getCurrentScreen() - 1);return true;}} else if (direction == View.FOCUS_RIGHT) {if (getCurrentScreen() < getChildCount() - 1) {snapToScreen(getCurrentScreen() + 1);return true;}}return super.dispatchUnhandledMove(focused, direction);}@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {if (mLocked) {return true;}final int action = ev.getAction();if ((action == MotionEvent.ACTION_MOVE) && (mTouchState != TOUCH_STATE_REST)) {return true;}final float x = ev.getX();final float y = ev.getY();switch (action) {case MotionEvent.ACTION_MOVE:final int xDiff = (int) Math.abs(x - mLastMotionX);final int yDiff = (int) Math.abs(y - mLastMotionY);final int touchSlop = mTouchSlop;boolean xMoved = xDiff > touchSlop;boolean yMoved = yDiff > touchSlop;if (xMoved || yMoved) {if (xMoved) {// Scroll if the user moved far enough along the X axismTouchState = TOUCH_STATE_SCROLLING;enableChildrenCache();}// Either way, cancel any pending longpressif (mAllowLongPress) {mAllowLongPress = false;// Try canceling the long press. It could also have been// scheduled// by a distant descendant, so use the mAllowLongPress flag// to block// everythingfinal View currentScreen = getChildAt(mCurrentScreen);currentScreen.cancelLongPress();}}break;case MotionEvent.ACTION_DOWN:// Remember location of down touchmLastMotionX = x;mLastMotionY = y;mAllowLongPress = true;mTouchState = mScroller.isFinished() ? TOUCH_STATE_REST : TOUCH_STATE_SCROLLING;break;case MotionEvent.ACTION_CANCEL:case MotionEvent.ACTION_UP:// Release the dragclearChildrenCache();mTouchState = TOUCH_STATE_REST;mAllowLongPress = false;break;}/* * The only time we want to intercept motion events is if we are in the * drag mode. */return mTouchState != TOUCH_STATE_REST;}void enableChildrenCache() {final int count = getChildCount();for (int i = 0; i < count; i++) {final View layout = (View) getChildAt(i);layout.setDrawingCacheEnabled(true);}}void clearChildrenCache() {final int count = getChildCount();for (int i = 0; i < count; i++) {final View layout = (View) getChildAt(i);layout.setDrawingCacheEnabled(false);}}@Overridepublic boolean onTouchEvent(MotionEvent ev) {if (mLocked) {return true;}if (mVelocityTracker == null) {mVelocityTracker = VelocityTracker.obtain();}mVelocityTracker.addMovement(ev);final int action = ev.getAction();final float x = ev.getX();switch (action) {case MotionEvent.ACTION_DOWN:/* * If being flinged and user touches, stop the fling. isFinished * will be false if being flinged. */if (!mScroller.isFinished()) {mScroller.abortAnimation();}// Remember where the motion event startedmLastMotionX = x;break;case MotionEvent.ACTION_MOVE:if (mTouchState == TOUCH_STATE_SCROLLING) {// Scroll to follow the motion eventfinal int deltaX = (int) (mLastMotionX - x);mLastMotionX = x;if (deltaX < 0) {if (getScrollX() > 0) {scrollBy(Math.max(-getScrollX(), deltaX), 0);}} else if (deltaX > 0) {final int availableToScroll = getChildAt(getChildCount() - 1).getRight() - getScrollX()- getWidth();if (availableToScroll > 0) {scrollBy(Math.min(availableToScroll, deltaX), 0);}}}break;case MotionEvent.ACTION_UP:if (mTouchState == TOUCH_STATE_SCROLLING) {final VelocityTracker velocityTracker = mVelocityTracker;velocityTracker.computeCurrentVelocity(1000);int velocityX = (int) velocityTracker.getXVelocity();if (velocityX > SNAP_VELOCITY && mCurrentScreen > 0) {// Fling hard enough to move leftsnapToScreen(mCurrentScreen - 1);} else if (velocityX < -SNAP_VELOCITY && mCurrentScreen < getChildCount() - 1) {// Fling hard enough to move rightsnapToScreen(mCurrentScreen + 1);} else {snapToDestination();}if (mVelocityTracker != null) {mVelocityTracker.recycle();mVelocityTracker = null;}}mTouchState = TOUCH_STATE_REST;break;case MotionEvent.ACTION_CANCEL:mTouchState = TOUCH_STATE_REST;}return true;}protected void snapToDestination() {int whichScreen = 0;int count = getChildCount();int start = 0;int end = 0;int viewWidth = 0;int tend = 0;int tstart = 0;final int scrollX = getScrollX();for (int i = 0; i < count; i++) {viewWidth = getChildAt(i).getWidth();tend = end + viewWidth / 2;if (i != 0) {viewWidth = getChildAt(i - 1).getWidth();}tstart -= viewWidth;if (scrollX > tstart && scrollX < tend) {break;}start += viewWidth;end += viewWidth;whichScreen++;}snapToScreen(whichScreen);}/** * 正常点击的切屏动画 *  * @param whichScreen *            1代表侧边收起 ,0代表展开侧边 *  */public void snapToScreen(int whichScreen) {enableChildrenCache();whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1));boolean changingScreens = whichScreen != mCurrentScreen;mNextScreen = whichScreen;View focusedChild = getFocusedChild();if (focusedChild != null && changingScreens && focusedChild == getChildAt(mCurrentScreen)) {focusedChild.clearFocus();}int newX = 0;for (int i = 0; i < whichScreen; i++) {newX += getChildAt(i).getWidth();}newX = Math.min(totalWidth - getWidth(), newX);final int delta = newX - getScrollX();// mScroller.startScroll(getScrollX(), 0, delta, 0, Math.abs(delta) *// 2);mScroller.startScroll(getScrollX(), 0, delta, 0, 500);invalidate();}/** *  * 点击左侧菜单的切屏动画 *  * @param whichScreen */public void closeMenu_1(int whichScreen) {enableChildrenCache();whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1));boolean changingScreens = whichScreen != mCurrentScreen;mNextScreen = whichScreen;View focusedChild = getFocusedChild();if (focusedChild != null && changingScreens && focusedChild == getChildAt(mCurrentScreen)) {focusedChild.clearFocus();}int newX = 0;for (int i = 0; i < whichScreen; i++) {newX += getChildAt(i).getWidth();}newX = Math.min(totalWidth - getWidth(), newX);final int delta = newX - getScrollX();mScroller.startScroll(getScrollX(), 0, delta - getWidth(), 0, 260);invalidate();}/** *  * 点击左侧菜单的切屏动画 *  * @param whichScreen */public void closeMenu_2(int whichScreen) {enableChildrenCache();whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1));boolean changingScreens = whichScreen != mCurrentScreen;mNextScreen = whichScreen;View focusedChild = getFocusedChild();if (focusedChild != null && changingScreens && focusedChild == getChildAt(mCurrentScreen)) {focusedChild.clearFocus();}int newX = 0;for (int i = 0; i < whichScreen; i++) {newX += getChildAt(i).getWidth();}newX = Math.min(totalWidth - getWidth(), newX);final int delta = newX - getScrollX();mScroller.startScroll(getScrollX(), 0, getWidth(), 0, 500);invalidate();}public int getScreenForView(View v) {int result = -1;if (v != null) {ViewParent vp = v.getParent();int count = getChildCount();for (int i = 0; i < count; i++) {if (vp == getChildAt(i)) {return i;}}}return result;}public void unlock() {mLocked = false;}public void lock() {mLocked = true;}void moveToDefaultScreen() {snapToScreen(mDefaultScreen);getChildAt(mDefaultScreen).requestFocus();}@Overrideprotected void onFinishInflate() {// TODO Auto-generated method stubsuper.onFinishInflate();View child;for (int i = 0; i < getChildCount(); i++) {child = getChildAt(i);child.setFocusable(true);child.setClickable(true);}}public void setCloseAnimation(CloseAnimation closeAnimation) {this.closeAnimation = closeAnimation;}public interface CloseAnimation {public void closeMenuAnimation();}}

1、MainActivity主界面

package com.zhuixingba.main;import com.zhuixingba.view.SlidingMenuView;import com.zhuixingba.view.SlidingMenuView.CloseAnimation;import android.os.Bundle;import android.app.ActivityGroup;import android.content.Intent;import android.util.Log;import android.view.KeyEvent;import android.view.View;import android.view.View.OnClickListener;import android.view.ViewGroup;import android.widget.Toast;public class MainActivity extends ActivityGroup implements OnClickListener {public static SlidingMenuView slidingMenuView;private ViewGroup tabcontent;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);slidingMenuView = (SlidingMenuView) findViewById(R.id.main_menu_view);tabcontent = (ViewGroup) slidingMenuView.findViewById(R.id.main_body);initView();}/** * 初始化控件 */private void initView() {// 加载主页Intent i = new Intent(this, HomePageActivity.class);View v = getLocalActivityManager().startActivity(HomePageActivity.class.getName(), i).getDecorView();tabcontent.removeAllViews();tabcontent.addView(v);findViewById(R.id.btn_homepage).setOnClickListener(this);findViewById(R.id.btn_stars).setOnClickListener(this);findViewById(R.id.btn_personal).setOnClickListener(this);findViewById(R.id.btn_hotapp).setOnClickListener(this);findViewById(R.id.btn_set).setOnClickListener(this);findViewById(R.id.btn_exit).setOnClickListener(this);tabcontent.setOnClickListener(this);}/** * 点击事件 */@Overridepublic void onClick(View v) {// TODO Auto-generated method stubswitch (v.getId()) {case R.id.btn_homepage:// 首页showActivity(HomePageActivity.class);break;case R.id.btn_stars:// 关注明星showActivity(StarsActivity.class);break;case R.id.btn_personal:// 个人资料showActivity(PersonalActivity.class);break;case R.id.btn_hotapp:// 热点应用showActivity(HotAPPActivity.class);break;case R.id.btn_set:// 设置showActivity(SetActivity.class);break;case R.id.btn_exit:// 退出this.finish();break;case R.id.main_body:slidingMenuView.snapToScreen(1);break;default:break;}}/** * 切换Activity的方法 *  * @param c *            参数为Activity */private void showActivity(Class<?> c) {Intent i = new Intent(this, c);View view = getLocalActivityManager().startActivity(c.getName(), i).getDecorView();tabcontent.removeAllViews();tabcontent.addView(view);slidingMenuView.setCloseAnimation(new CloseAnimation() {@Overridepublic void closeMenuAnimation() {// TODO Auto-generated method stubif (-slidingMenuView.getScrollX() == getWindowManager().getDefaultDisplay().getWidth()- (slidingMenuView.totalWidth - getWindowManager().getDefaultDisplay().getWidth())) {slidingMenuView.closeMenu_2(1);}}});slidingMenuView.closeMenu_1(1);}private long exitTime = 0;@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {if (slidingMenuView.getCurrentScreen() == 1) {if ((System.currentTimeMillis() - exitTime) > 2000) {Toast.makeText(getApplicationContext(), "再按一次退出程序", Toast.LENGTH_SHORT).show();exitTime = System.currentTimeMillis();} else {finish();System.exit(0);}} else {slidingMenuView.snapToScreen(1);}return true;} else if (keyCode == KeyEvent.KEYCODE_MENU && event.getAction() == KeyEvent.ACTION_DOWN) {if (slidingMenuView.getCurrentScreen() == 1) {slidingMenuView.snapToScreen(0);} else {slidingMenuView.snapToScreen(1);}return true;}return super.onKeyDown(keyCode, event);}}

3、MainActivity界面xml文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="fill_parent"    android:layout_height="fill_parent" >    <com.zhuixingba.view.SlidingMenuView        android:id="@+id/main_menu_view"        android:layout_width="fill_parent"        android:layout_height="fill_parent" >        <LinearLayout            android:id="@+id/main_left_menu"            android:layout_width="240dip"            android:layout_height="fill_parent"            android:background="@android:color/darker_gray"            android:orientation="vertical"            android:padding="5dip" >            <Button                android:id="@+id/btn_homepage"                android:layout_width="240dip"                android:layout_height="wrap_content"                android:text="@string/left_menu_homepage" />            <Button                android:id="@+id/btn_stars"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:text="@string/left_menu_stars" />            <Button                android:id="@+id/btn_personal"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:text="@string/left_menu_personal" />            <Button                android:id="@+id/btn_hotapp"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:text="@string/left_menu_hotapp" />            <Button                android:id="@+id/btn_set"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:text="@string/left_menu_set" />            <Button                android:id="@+id/btn_exit"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:text="@string/left_menu_exit" />        </LinearLayout>        <FrameLayout            android:id="@+id/main_body"            android:layout_width="fill_parent"            android:layout_height="fill_parent" >        </FrameLayout>    </com.zhuixingba.view.SlidingMenuView></RelativeLayout>

4、菜单界面点击显示左边菜单事件


if (MainActivity.slidingMenuView.getCurrentScreen() == 1) {MainActivity.slidingMenuView.snapToScreen(0);} else {MainActivity.slidingMenuView.snapToScreen(1);}



更多相关文章

  1. android navigationdrawer抽屉菜单
  2. [Android]Fragment点击穿透问题
  3. 给recyclerAdapter打造通用点击事件监听设置BaseRecyclerAdapter
  4. 弹出式菜单PopMenu
  5. Android实现点击切换视图并跳转传值
  6. Android轮播广告条NoticeView
  7. Android(安卓)ListView 中的CheckBox点击乱系
  8. 布局参数说明及长按某区域出现菜单
  9. android XMl Selector 图片背景点击和焦点获取样式

随机推荐

  1. 获得G1的电池电量信息
  2. AndroidStudio、gradle、buildToolsVersi
  3. sqlite c库使用
  4. Android Sensor详解(6)sensor framework层
  5. Android greenDao 使用教程(二) 在Eclipse
  6. Android中定义Viewport需要注意的几个数
  7. Baidu Map开发示例
  8. 【Android Developers Training】 74. 序
  9. GoBelieve,IMSDK android版开发环境问题
  10. Animation and Graphics partⅠ Overview