Android 左边滑动菜单栏
来源:互联网 发布:室内温度测试软件 编辑:程序博客网 时间:2024/06/11 05:20
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);}
0 0
- Android 左边滑动菜单栏
- Android左边菜单栏导航
- android顶部菜单栏+滑动图片
- ubuntu 左边菜单栏不见
- android之SlidingMenu滑动菜单栏使用介绍
- android 仿美团、大众点评滑动viewpager菜单栏
- 【Android】viewpager+fragment+tablayout实现滑动菜单栏
- Android 实现类似QQ的 左边滑动删除
- Android:滑动菜单栏(三)SlidingMenu动画效果的实现
- Android 高仿QQ HD mini左右滑动菜单栏效果
- Android:菜单栏Menubar跟随ListView滑动隐藏和显示
- Android开发之欢迎界面和滑动弹出菜单栏效果
- Android使用TabLayout+ViewPager实现顶部滑动菜单栏
- 菜单栏滑动效果
- iOS左侧滑动菜单栏
- 实现滑动菜单栏demo
- CSS滑动门横向菜单栏
- IE6支持的滑动菜单栏
- 神秘金主悬赏10万 路上刊登巨幅广告寻“女神”
- 经典模板
- 全渠道零售-新的消费者购物体验-林守常
- 让UILabel的文字顶部对齐【补充了一点点】
- elasitcsearch漏洞在线检测工具
- Android 左边滑动菜单栏
- jquery ajax 提交表单
- hi3531的pcie atu资源重映射
- C# 数据类型后加问号
- hdu 3068 最长回文
- hadoop2.4汇总:hadoop2.4插件下载、完全分布式、伪分布、eclipse插件开发大全
- Visual Studio .NET 2003 安装时的1309错误
- Python之os.walk和os.path.walk
- rand前用srand