仿QQmini的侧滑效果SlidingMenu
2013-01-09 14:37
141 查看
Slidingmenu很多地方都有。。之前项目有要求模仿QQmini的,所以现在记录一下, 2013-1-9 22:28最后更改,不去记录pointID,暂时处理不好,在拖动的时候在点击滑动页面就会出现getX()越界, MotionEvent.java没细看,先这样吧...
android 的touch事件处理请参考我转载的一篇文章:/article/10245706.html
转载请注明出处/article/10245707.html
先看效果图
效果比较挫。。。。将就吧。。。源码我将会放到CSDN上面需要的可以下载
自定义控件的代码:
代码下载地址http://download.csdn.net/detail/feng283797821/4977504
有个开源的 https://github.com/jfeinstein10/SlidingMenu
android 的touch事件处理请参考我转载的一篇文章:/article/10245706.html
转载请注明出处/article/10245707.html
先看效果图
效果比较挫。。。。将就吧。。。源码我将会放到CSDN上面需要的可以下载
自定义控件的代码:
package com.feng.view; import com.feng.qqmini.R; import com.feng.utils.Util; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.GestureDetector; import android.view.GestureDetector.OnGestureListener; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.view.animation.AnimationUtils; import android.widget.LinearLayout; import android.widget.Scroller; public class HomeCenterLayout extends LinearLayout { private final static String TAG = "HomeCenterLayout"; public final int MENU_border_Width = 40; private Scroller mScroller; private GestureDetector gestureDetector; private LinearLayout leftLayout, rightLayout, childLayout; private Context context; private boolean fling; private boolean mIsBeingDragged = false; private int mTouchSlop; /** * Position of the last motion event. */ private float mLastMotionX, mLastMotionY; /** * ID of the active pointer. This is used to retain consistency during * drags/flings if multiple pointers are used. */ //private int mActivePointerId = INVALID_POINTER; /** * Sentinel value for no current active pointer. * Used by {@link #mActivePointerId}. */ private static final int INVALID_POINTER = -1; int menuWidth = 0; int moveWidth = 0; public HomeCenterLayout(Context context, AttributeSet attrs) { super(context, attrs); initView(context); } public HomeCenterLayout(Context context) { super(context); initView(context); } public Scroller getScroller() { return mScroller; } public void initView(Context context) { this.context = context; this.menuWidth = MENU_border_Width; this.mScroller = new Scroller(context,AnimationUtils.loadInterpolator(context, android.R.anim.overshoot_interpolator)); final ViewConfiguration configuration = ViewConfiguration.get(context); mTouchSlop = configuration.getScaledTouchSlop(); } public void addChildView(View child) { this.childLayout.addView(child); } @Override protected void onLayout(boolean changed, int left, int top, int right,int bottom) { super.onLayout(changed, left, top, right, bottom); // Log.i(TAG + " onLayout", "on layout "+changed+" "+left+" "+top+" "+right+" "+bottom); for (int i = 0; i < getChildCount(); i++) { View child = getChildAt(i); child.layout(child.getLeft()+moveWidth,child.getTop(),child.getRight()+moveWidth,child.getBottom()); } } @Override public void computeScroll() { if (mScroller.computeScrollOffset()) { scrollTo(mScroller.getCurrX(), 0); postInvalidate(); } } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { // TODO Auto-generated method stub Log.i(TAG, "onInterceptTouchEvent------>"+ev.getAction()); final int action = ev.getAction(); if ((action == MotionEvent.ACTION_MOVE) && (mIsBeingDragged)) { return true;//拦截不传递给child view } switch (action & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: { final float x = ev.getX(); final float y = ev.getY(); if (!inChild((int)x, (int) y)) { mIsBeingDragged = false; break; //超出边界,return false传递给子view处理 } /* * Remember location of down touch. * ACTION_DOWN always refers to pointer index 0. */ mLastMotionX = x; mLastMotionY = y; //mActivePointerId = ev.getPointerId(0); /* * If being flinged and user touches the screen, initiate drag; * otherwise don't. mScroller.isFinished should be false when * being flinged. */ mIsBeingDragged = !mScroller.isFinished(); break; } case MotionEvent.ACTION_MOVE: { /* * mIsBeingDragged == false, otherwise the shortcut would have caught it. Check * whether the user has moved far enough from his original down touch. */ /* * Locally do absolute value. mLastMotionY is set to the y value * of the down event. */ final int activePointerId = mActivePointerId; if (activePointerId == INVALID_POINTER) { // If we don't have a valid id, the touch down wasn't on content. break; } //final int pointerIndex = ev.findPointerIndex(activePointerId); final float x = ev.getX(/*pointerIndex*/); final float y = ev.getY(/*pointerIndex*/); final int xDiff = (int) Math.abs(x - mLastMotionX); final int yDiff = (int) Math.abs(y - mLastMotionY); if (xDiff > mTouchSlop && yDiff < xDiff) { mIsBeingDragged = true; //mLastMotionX = x; //mLastMotionY = y; } break; } case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: mIsBeingDragged = false; //mActivePointerId = INVALID_POINTER; snapToDestination(); break; } return mIsBeingDragged; } @Override public boolean onTouchEvent(MotionEvent event) { Log.i(TAG, "onTouchEvent ---->>>>>"+event.getAction()); if (event.getAction() == MotionEvent.ACTION_DOWN && !inChild((int)event.getX(), (int)event.getY())) { // Don't handle edge touches immediately -- they may actually belong to one of our // descendants. return false; } switch(event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: { return true; //本VIEW消化掉 //break; } case MotionEvent.ACTION_MOVE: { /*if(mIsBeingDragged)*/ { //final int activePointerIndex = event.findPointerIndex(mActivePointerId); final float x = event.getX(/*activePointerIndex*/); final float y = event.getY(/*activePointerIndex*/); final int distanceX = (int) /*Math.abs*/-(x - mLastMotionX); if( distanceX < 0 && getScrollX() < 0 && leftLayout != null) { setBrotherVisibility(true); } else if(distanceX > 0 && getScrollX() > 0 && rightLayout != null) { setBrotherVisibility(false); } else { } scrollBy((int) distanceX, 0); mLastMotionX = x; mLastMotionY = y; } break; } case MotionEvent.ACTION_UP: { mIsBeingDragged = false; //mActivePointerId = INVALID_POINTER; snapToDestination(); break; } default: return super.onTouchEvent(event); } return mIsBeingDragged; } @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { // TODO Auto-generated method stub super.onScrollChanged(l, t, oldl, oldt); } public void scrollToScreen() { /* if (getFocusedChild() != null && whichScreen != currentScreenIndex && getFocusedChild() == getChildAt(currentScreenIndex)) { getFocusedChild().clearFocus(); }*/ int scrollDistance = 0;//getWidth()*(getChildCount()-whichScreen) - getScrollX(); if(Math.abs(getScrollX()) > getWidth()/2) scrollDistance = (getScrollX() > 0) ? getWidth()-menuWidth-getScrollX() : -(getWidth()-menuWidth-Math.abs(getScrollX())); else scrollDistance = -getScrollX(); // Log.i(TAG, " scrollDistance = "+scrollDistance); mScroller.startScroll(getScrollX(), 0, scrollDistance, 0, Math.abs(scrollDistance) * 2); invalidate(); } public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { // Log.d(TAG, "on onFling>>>"); if (Math.abs(velocityX) > ViewConfiguration.get(context).getScaledMinimumFlingVelocity()) { fling = true; snapToDestination(); } return true; } private void snapToDestination() { // Log.i(TAG+" snapToDestination", "getScrollX() = "+getScrollX() + " getWidth()="+getWidth()); scrollToScreen(); } private boolean inChild(int x, int y) { if (getChildCount() > 0) { final int scrollX = mScroller.getCurrX(); final View child = getChildAt(0); return !(scrollX + x < 0 || scrollX + x > getWidth() || y < 0 || y> getHeight()); } return false; } /** * @param String类型 "left", "right", "middle"/"other" 忽略大小写 * */ public void setSkipToWhichPage(String whichpg) { int targetX = 0, moveDistance = 0; if(whichpg.equalsIgnoreCase("left")) { targetX = -(Util.getViewWidthInPix(context) - menuWidth); setBrotherVisibility(true); } else if(whichpg.equalsIgnoreCase("right")) { targetX = Util.getViewWidthInPix(context) - menuWidth; setBrotherVisibility(false); } else ; moveDistance = targetX - getScrollX(); Log.i(VIEW_LOG_TAG, "targetX="+targetX+",moveDistance="+moveDistance); mScroller.startScroll(getScrollX(), 0, moveDistance, 0, 0); invalidate(); } public void setBrotherLayout(LinearLayout left, LinearLayout right) { this.leftLayout = left; this.rightLayout = right; } private void setBrotherVisibility(boolean leftSide) { if(leftSide) { rightLayout.setVisibility(View.GONE); leftLayout.setVisibility(View.VISIBLE); } else { rightLayout.setVisibility(View.VISIBLE); leftLayout.setVisibility(View.GONE); } } }
代码下载地址http://download.csdn.net/detail/feng283797821/4977504
有个开源的 https://github.com/jfeinstein10/SlidingMenu
相关文章推荐
- SlidingMenu重写HorizontalScrollView实现菜单侧滑的效果
- SlidingMenu实现左侧侧滑效果
- android studio 导入SlidingMenu实现侧滑效果
- SlidingMenu实现侧滑效果
- android侧滑效果,SlidingMenu配置
- 如何把DrawLayout做出SlidingMenu的侧滑效果
- 【Android进阶】SlidingMenu实现侧滑栏效果的实现
- Android 自定义SlidingMenu 实现QQ5.0侧滑菜单动画效果
- 【Android界面实现】SlidingMenu实现侧滑栏效果
- Android中使用开源库slidingMenu实现侧滑效果
- android侧滑效果,SlidingMenu配置
- 他山之石之使用SlidingMenu实现侧滑的效果
- android侧滑效果,SlidingMenu配置
- Android 高仿 QQ5.0 侧滑菜单效果 自定义控件来袭
- Android开源项目侧滑SlidingMenu的使用
- Android 高仿 QQ5.0 侧滑菜单效果
- 【FastDev4Android框架开发】打造QQ6.X最新版本侧滑界面效果(三十八)
- drawerlayout实现侧滑效果
- 【Android UI设计与开发】第18期:滑动菜单栏(三)SlidingMenu动画效果的实现
- SlidingMenu(侧滑框)的使用、ViewPager冲突处理