仿QQmini的侧滑效果SlidingMenu
来源:互联网 发布:cpu超频软件 编辑:程序博客网 时间:2024/05/01 16:37
Slidingmenu很多地方都有。。之前项目有要求模仿QQmini的,所以现在记录一下, 2013-1-9 22:28最后更改,不去记录pointID,暂时处理不好,在拖动的时候在点击滑动页面就会出现getX()越界, MotionEvent.java没细看,先这样吧...
android 的touch事件处理请参考我转载的一篇文章:http://blog.csdn.net/feng283797821/article/details/8485522
转载请注明出处http://blog.csdn.net/feng283797821/article/details/8485382
先看效果图
效果比较挫。。。。将就吧。。。源码我将会放到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);} @Overrideprotected 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());}} @Overridepublic void computeScroll() {if (mScroller.computeScrollOffset()) { scrollTo(mScroller.getCurrX(), 0); postInvalidate();}} @Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {// TODO Auto-generated method stubLog.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;}@Overridepublic 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;} @Overrideprotected void onScrollChanged(int l, int t, int oldl, int oldt) {// TODO Auto-generated method stubsuper.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()));elsescrollDistance = -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
- 仿QQmini的侧滑效果SlidingMenu
- Android 高仿 QQ5.2 侧滑菜单效果及QQmini效果
- 最简单的基于SlidingMenu仿QQ侧滑效果
- 关于侧滑效果SlidingMenu
- SlidingMenu实现侧滑效果
- 仿SlidingMenu自定义QQ侧滑菜单
- 仿SlidingMenu的实现原理,例SlidingMenu
- 如何把DrawLayout做出SlidingMenu的侧滑效果
- SlidingMenu重写HorizontalScrollView实现菜单侧滑的效果
- 他山之石之使用SlidingMenu实现侧滑的效果
- SlidingMenu+ViewPager实现侧滑菜单效果
- android侧滑效果,SlidingMenu配置
- android侧滑效果,SlidingMenu配置
- Android UI-SlidingMenu侧滑菜单效果
- SlidingMenu实现左侧侧滑效果
- Android UI-SlidingMenu侧滑菜单效果
- 修改slidingmenu仿QQ5.0侧滑菜单
- 仿SlidingMenu
- 实现链表的逆序输出和删除某节点
- ios开发之打开系统及自己的应用程序
- SQL SERVER 2008 集群添加存储
- jsp连接mysql数据库查询
- 集中式计算助力虚拟化桌面
- 仿QQmini的侧滑效果SlidingMenu
- centos 6.3 安装realtek RTL8188CE无线网卡
- RedHat Enterprise 5 Mono移植全新体验旅程
- const总结
- Linux系统信息查看命令大全
- 视频网站刮起选秀风 56网携百度视频征集网络红人
- linux下的scp命令
- 【Android】制作签名认证apk并部署的过程
- 串行通讯的根本原理及用MFC实现串口通讯编程