Android UI开发第二十七篇——实现左右划出菜单
生活随笔
收集整理的這篇文章主要介紹了
Android UI开发第二十七篇——实现左右划出菜单
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
? ? ? ?年前就想寫左右滑動菜單,苦于沒有時間,一直拖到現(xiàn)在,這篇代碼實(shí)現(xiàn)參考了網(wǎng)上流行的SlidingMenu,使用的FrameLayout布局,不是擴(kuò)展的HorizontalScrollView。
? ? ? ?程序中自定義了菜單view:SlidingView,繼承自ViewGroup,使用FrameLayout布局。重寫了onInterceptTouchEvent(MotionEvent ev)方法實(shí)現(xiàn)ontouch的分發(fā)攔截,重寫了onTouchEvent(MotionEvent ev)方法,實(shí)現(xiàn)左右滑動。
?
public class SlidingView extends ViewGroup {private FrameLayout mContainer;private Scroller mScroller;private VelocityTracker mVelocityTracker;private int mTouchSlop;private float mLastMotionX;private float mLastMotionY;private static final int SNAP_VELOCITY = 1000;private View mLeftView;private View mRightView;public SlidingView(Context context) {super(context);init();}public SlidingView(Context context, AttributeSet attrs) {super(context, attrs);init();}public SlidingView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);init();}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);mContainer.measure(widthMeasureSpec, heightMeasureSpec);}@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {final int width = r - l;final int height = b - t;mContainer.layout(0, 0, width, height);}private void init() {mContainer = new FrameLayout(getContext());mContainer.setBackgroundColor(0xff000000);mScroller = new Scroller(getContext());mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();super.addView(mContainer);}public void setView(View v) {if (mContainer.getChildCount() > 0) {mContainer.removeAllViews();}mContainer.addView(v);}@Overridepublic void scrollTo(int x, int y) {super.scrollTo(x, y);postInvalidate();}@Overridepublic void computeScroll() {if (!mScroller.isFinished()) {if (mScroller.computeScrollOffset()) {int oldX = getScrollX();int oldY = getScrollY();int x = mScroller.getCurrX();int y = mScroller.getCurrY();if (oldX != x || oldY != y) {scrollTo(x, y);}// Keep on drawing until the animation has finished.invalidate();} else {clearChildrenCache();}} else {clearChildrenCache();}}private boolean mIsBeingDragged;/*** 實(shí)現(xiàn)了ontouch的分發(fā)攔截*/@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {final int action = ev.getAction();final float x = ev.getX();final float y = ev.getY();switch (action) {case MotionEvent.ACTION_DOWN:mLastMotionX = x;mLastMotionY = y;mIsBeingDragged = false;break;case MotionEvent.ACTION_MOVE:final float dx = x - mLastMotionX;final float xDiff = Math.abs(dx);final float yDiff = Math.abs(y - mLastMotionY);if (xDiff > mTouchSlop && xDiff > yDiff) {mIsBeingDragged = true;mLastMotionX = x;}Log.d("Sliding", "SlidingView_Touch:"+x+"|"+y);Log.d("Sliding", "SlidingView_Touch:"+xDiff+"|"+mTouchSlop+"|"+yDiff+"|"+mLastMotionY);Log.d("Sliding", "SlidingView_Touch:"+mIsBeingDragged);break;}return mIsBeingDragged;}@Overridepublic boolean onTouchEvent(MotionEvent ev) {if (mVelocityTracker == null) {mVelocityTracker = VelocityTracker.obtain();}mVelocityTracker.addMovement(ev);final int action = ev.getAction();final float x = ev.getX();final float y = ev.getY();switch (action) {case MotionEvent.ACTION_DOWN:if (!mScroller.isFinished()) {mScroller.abortAnimation();}mLastMotionX = x;mLastMotionY = y;if (getScrollX() == -getLeftMenuWidth()&& mLastMotionX < getLeftMenuWidth()) {return false;}if (getScrollX() == getRightMenuWidth()&& mLastMotionX > getLeftMenuWidth()) {return false;}break;case MotionEvent.ACTION_MOVE:if (mIsBeingDragged) {enableChildrenCache();final float deltaX = mLastMotionX - x;mLastMotionX = x;float oldScrollX = getScrollX();float scrollX = oldScrollX + deltaX;if (deltaX < 0 && oldScrollX < 0) { // left viewfinal float leftBound = 0;final float rightBound = -getLeftMenuWidth();if (scrollX > leftBound) {scrollX = leftBound;} else if (scrollX < rightBound) {scrollX = rightBound;}} else if (deltaX > 0 && oldScrollX > 0) { // right viewfinal float rightBound = getRightMenuWidth();final float leftBound = 0;if (scrollX < leftBound) {scrollX = leftBound;} else if (scrollX > rightBound) {scrollX = rightBound;}}scrollTo((int) scrollX, getScrollY());if (scrollX > 0) {mLeftView.setVisibility(View.GONE);mLeftView.clearFocus();mRightView.setVisibility(View.VISIBLE);mRightView.requestFocus();} else {mLeftView.setVisibility(View.VISIBLE);mLeftView.requestFocus();mRightView.setVisibility(View.GONE);mRightView.clearFocus();}}break;case MotionEvent.ACTION_CANCEL:case MotionEvent.ACTION_UP:if (mIsBeingDragged) {final VelocityTracker velocityTracker = mVelocityTracker;velocityTracker.computeCurrentVelocity(1000);int velocityX = (int) velocityTracker.getXVelocity();velocityX = 0;int oldScrollX = getScrollX();int dx = 0;if (oldScrollX < 0) {// 左邊if (oldScrollX < -getLeftMenuWidth() / 2|| velocityX > SNAP_VELOCITY) {// 左側(cè)頁面劃出dx = -getLeftMenuWidth() - oldScrollX;} else if (oldScrollX >= -getLeftMenuWidth() / 2|| velocityX < -SNAP_VELOCITY) {// 左側(cè)頁面關(guān)閉dx = -oldScrollX;}} else {// 右邊if (oldScrollX > getRightMenuWidth() / 2|| velocityX < -SNAP_VELOCITY) {// 右側(cè)頁面劃出dx = getRightMenuWidth() - oldScrollX;} else if (oldScrollX <= getRightMenuWidth() / 2|| velocityX > SNAP_VELOCITY) {// 右側(cè)頁面關(guān)閉dx = -oldScrollX;}}smoothScrollTo(dx);clearChildrenCache();}break;}if (mVelocityTracker != null) {mVelocityTracker.recycle();mVelocityTracker = null;}return true;}private int getLeftMenuWidth() {if (mLeftView == null) {return 0;}return mLeftView.getWidth();}private int getRightMenuWidth() {if (mRightView == null) {return 0;}return mRightView.getWidth();}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);}public View getRightView() {return mRightView;}public void setRightView(View mRightView) {this.mRightView = mRightView;}public View getMenuView() {return mLeftView;}public void setLeftView(View mLeftView) {this.mLeftView = mLeftView;}void toggle() {int menuWidth = mLeftView.getWidth();int oldScrollX = getScrollX();if (oldScrollX == 0) {smoothScrollTo(-menuWidth);} else if (oldScrollX == -menuWidth) {smoothScrollTo(menuWidth);}}/*** 打開(關(guān)閉)左側(cè)頁面*/public void showLeftView() {mLeftView.setVisibility(View.VISIBLE);mRightView.setVisibility(View.GONE);int menuWidth = mLeftView.getWidth();int oldScrollX = getScrollX();if (oldScrollX == 0) {smoothScrollTo(-menuWidth);} else if (oldScrollX == -menuWidth) {smoothScrollTo(menuWidth);}}/*** 打開(關(guān)閉)右側(cè)頁面*/public void showRightView() {mLeftView.setVisibility(View.GONE);mLeftView.clearFocus();mRightView.setVisibility(View.VISIBLE);mRightView.requestFocus();int menuWidth = mRightView.getWidth();int oldScrollX = getScrollX();if (oldScrollX == 0) {smoothScrollTo(menuWidth);} else if (oldScrollX == menuWidth) {smoothScrollTo(-menuWidth);}}/*** 顯示中間頁面*/public void showCenterView() {int menuWidth = mRightView.getWidth();int oldScrollX = getScrollX();if (oldScrollX == menuWidth) {showRightView();} else if (oldScrollX == -menuWidth) {showLeftView();}}void smoothScrollTo(int dx) {int duration = 500;int oldScrollX = getScrollX();mScroller.startScroll(oldScrollX, getScrollY(), dx, getScrollY(),duration);invalidate();}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);}}}
SlidingMenu對SlidingView做了進(jìn)一步封裝處理:
?
?
public class SlidingMenu extends RelativeLayout {private SlidingView mSlidingView;private View mLeftView;private View mRightView;// menu widthprivate int alignScreenWidth;public SlidingMenu(Context context) {super(context);}public SlidingMenu(Context context, AttributeSet attrs) {super(context, attrs);}public SlidingMenu(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);}public void setAlignScreenWidth(int alignScreenWidth) {this.alignScreenWidth = alignScreenWidth;}public void setLeftView(View view) {LayoutParams behindParams = new LayoutParams(alignScreenWidth,LayoutParams.MATCH_PARENT);addView(view, behindParams);mLeftView = view;}public void setRightView(View view) {LayoutParams behindParams = new LayoutParams(alignScreenWidth,LayoutParams.MATCH_PARENT);behindParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);addView(view, behindParams);mRightView = view;}public void setCenterView(View view) {LayoutParams aboveParams = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);mSlidingView = new SlidingView(getContext());addView(mSlidingView, aboveParams);mSlidingView.setView(view);mSlidingView.invalidate();mSlidingView.setLeftView(mLeftView);mSlidingView.setRightView(mRightView);}public void showLeftView() {mSlidingView.showLeftView();}public void showRightView() {mSlidingView.showRightView();}public void showCenterView() {mSlidingView.showCenterView();}}?
SlidingMenu的使用代碼
?
public class SlidingActivity extends Activity implements OnClickListener{SlidingMenu mSlidingMenu;@Overrideprotected void onCreate(Bundle arg0) {super.onCreate(arg0);setContentView(R.layout.main);DisplayMetrics dm = new DisplayMetrics();getWindowManager().getDefaultDisplay().getMetrics(dm);mSlidingMenu = (SlidingMenu) findViewById(R.id.slidingMenu);mSlidingMenu.setAlignScreenWidth((dm.widthPixels / 5) * 2);View leftView=getLayoutInflater().inflate(R.layout.left_menu, null);View rightView=getLayoutInflater().inflate(R.layout.right_menu, null);View centerView=getLayoutInflater().inflate(R.layout.center, null);mSlidingMenu.setLeftView(leftView);mSlidingMenu.setRightView(rightView);mSlidingMenu.setCenterView(centerView);Button showLeftMenu=(Button)centerView.findViewById(R.id.center_left_btn);showLeftMenu.setOnClickListener(this);Button showRightMenu=(Button)centerView.findViewById(R.id.center_right_btn);showRightMenu.setOnClickListener(this);}@Overridepublic void onClick(View v) {// TODO Auto-generated method stubswitch (v.getId()) {case R.id.center_left_btn:mSlidingMenu.showLeftView();break;case R.id.center_right_btn:mSlidingMenu.showRightView();break;default:break;}}}? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
?
代碼:http://download.csdn.net/detail/xyz_lmn/5109965
?
?
/** * @author 張興業(yè) * ?http://blog.csdn.net/xyz_lmn * ?iOS入門群:83702688* ?android開發(fā)進(jìn)階群:241395671 * ?我的新浪微博:@張興業(yè)TBOW * ?我的郵箱:xy-zhang#163.com(#->@) */
轉(zhuǎn)載于:https://www.cnblogs.com/xyzlmn/p/3168071.html
總結(jié)
以上是生活随笔為你收集整理的Android UI开发第二十七篇——实现左右划出菜单的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JavaScript中setAttrib
- 下一篇: 关于调试windows services