完美解决左侧抽屉菜单和viewpager不能兼容左右滑动的问题,可进行参考。

WeMall-Client/res/layout/wemall_main_ui.xml

</RadioGroup>
</RelativeLayout>
</cn.edu.zzu.wemall.ui.SlideMenu>

</RelativeLayout>
\ No newline at end of file

WeMall-Client/src/cn/edu/zzu/wemall/ui/MainUIMain.java

import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.Window;
import android.view.inputmethod.InputMethodManager;
@@ -105,6 +107,8 @@ public class MainUIMain extends FragmentActivity implements
menudata = new ArrayList<HashMap<String, Object>>();
menuadapter = new MenuAdapter(this, menudata);
menulistview.setAdapter(menuadapter);

// 初始化ViewPager,菜单数据
InitViewPager();
@@ -206,8 +210,9 @@ public class MainUIMain extends FragmentActivity implements
public void onPageScrollStateChanged(int arg0) {
// 在这里判断vpage是否滑到了商品页面,如果滑到了商品页面并且继续向右拉动屏幕,则展现菜单列表//
if (this.viewPager.getCurrentItem() == 0 && arg0 == 1) {
System.out.println("滑到了最左边且在基于往右侧滑动");
 //slideMenu.openMenu();

} else {

}
}

  

WeMall-Client/src/cn/edu/zzu/wemall/ui/SlideMenu.java

package cn.edu.zzu.wemall.ui;

import cn.edu.zzu.wemall.R;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.Scroller;

/*
 * 侧边栏类
 *
 */
public class SlideMenu extends ViewGroup {
	public static final int SCREEN_MENU = 0;
	public static final int SCREEN_MAIN = 1;
	private static final int SCREEN_INVALID = -1;

	private int mCurrentScreen;
	private int mNextScreen = SCREEN_INVALID;

	private Scroller mScroller;
	private VelocityTracker mVelocityTracker;
	private int mTouchSlop;

	private float mLastMotionX;
	private float mLastMotionY;

	private final static int TOUCH_STATE_REST = 0;
	private final static int TOUCH_STATE_SCROLLING = 1;
	private static final int SNAP_VELOCITY = 1000;

	public int mTouchState = TOUCH_STATE_REST;
	private boolean mLocked;
	private boolean mAllowLongPress;

	public SlideMenu(Context context) {
		this(context, null, 0);
	}

	public SlideMenu(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public SlideMenu(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);

		mScroller = new Scroller(getContext());
		mCurrentScreen = SCREEN_MAIN;
		mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		measureViews(widthMeasureSpec, heightMeasureSpec);
	}

	public void measureViews(int widthMeasureSpec, int heightMeasureSpec) {
		View menuView = getChildAt(0);
		menuView.measure(menuView.getLayoutParams().width + menuView.getLeft()
				+ menuView.getRight(), heightMeasureSpec);

		View contentView = getChildAt(1);
		contentView.measure(widthMeasureSpec, heightMeasureSpec);
	}

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		int childCount = getChildCount();
		if (childCount != 2) {
			throw new IllegalStateException(
					"The childCount of SlidingMenu must be 2");
		}

		View menuView = getChildAt(0);
		final int width = menuView.getMeasuredWidth();
		menuView.layout(-width, 0, 0, menuView.getMeasuredHeight());

		View contentView = getChildAt(1);
		contentView.layout(0, 0, contentView.getMeasuredWidth(),
				contentView.getMeasuredHeight());
	}

	@Override
	protected void onFinishInflate() {
		super.onFinishInflate();
		View child;
		for (int i = 0; i < getChildCount(); i++) {
			child = getChildAt(i);
			child.setFocusable(true);
			child.setClickable(true);
		}
	}

	@Override
	public 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:
			//在这里做点文章,侧滑菜单和viewpager的滑动兼容,头疼。。。
			/**
			 * 设定条件,如果当前页面在商品页面,往右侧拉动屏幕,显示菜单,往左则收回菜单,再往左拉
			 * 则切换到购物车
			 * 如果当前页面在购物车或者个人中心,则无论左右拉,都不理会菜单栏!,直接切换viewpager
			 */
			ViewPager viewPager = (ViewPager) findViewById(R.id.vPager);
			if(viewPager.getCurrentItem()>0){ //如果当前页面不在商品页面,则忽略滑动出现菜单
				break;
			}

			final int xDiff = (int) Math.abs(x - mLastMotionX);
			final int yDiff = (int) Math.abs(y - mLastMotionY);
			//菜单没显示且往右滑动时break
			if(isMainScreenShowing()&&(x - mLastMotionX)<0){
				break;
			}
			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 axis
					mTouchState = TOUCH_STATE_SCROLLING;
					enableChildrenCache();
				}
				// Either way, cancel any pending longpress
				if (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
					// everything
					final View currentScreen = getChildAt(mCurrentScreen);
					currentScreen.cancelLongPress();
				}
			}
			break;

		case MotionEvent.ACTION_DOWN:

			// Remember location of down touch
			mLastMotionX = 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 drag
			clearChildrenCache();
			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);
		}
	}

	@SuppressLint("ClickableViewAccessibility")
	@Override
	public 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 started
			mLastMotionX = x;
			break;
		case MotionEvent.ACTION_MOVE:
			if (mTouchState == TOUCH_STATE_SCROLLING) {
				// Scroll to follow the motion event
				final int deltaX = (int) (mLastMotionX - x);
				mLastMotionX = x;
				if (deltaX < 0) {
					if (deltaX + getScrollX() >= -getChildAt(0).getWidth()) {
						scrollBy(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 == SCREEN_MAIN) {
					// Fling hard enough to move left
					snapToScreen(SCREEN_MENU);
				} else if (velocityX < -SNAP_VELOCITY
						&& mCurrentScreen == SCREEN_MENU) {
					// Fling hard enough to move right
					snapToScreen(SCREEN_MAIN);
				} else {
					snapToDestination();
				}

				if (mVelocityTracker != null) {
					mVelocityTracker.recycle();
					mVelocityTracker = null;
				}
			}
			mTouchState = TOUCH_STATE_REST;
			break;
		case MotionEvent.ACTION_CANCEL:
			mTouchState = TOUCH_STATE_REST;
		}

		return true;
	}

	@Override
	public void computeScroll() {
		if (mScroller.computeScrollOffset()) {
			scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
		} else if (mNextScreen != SCREEN_INVALID) {
			mCurrentScreen = Math.max(0,
					Math.min(mNextScreen, getChildCount() - 1));
			mNextScreen = SCREEN_INVALID;
			clearChildrenCache();
		}
	}

	@Override
	public void scrollTo(int x, int y) {
		super.scrollTo(x, y);
		postInvalidate();
	}

	@Override
	protected void dispatchDraw(Canvas canvas) {
		final int scrollX = getScrollX();
		super.dispatchDraw(canvas);
		canvas.translate(scrollX, 0);
	}

	@Override
	public 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);
	}

	protected 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();
		}

		final int newX = (whichScreen - 1) * getChildAt(0).getWidth();
		final int delta = newX - getScrollX();
		mScroller.startScroll(getScrollX(), 0, delta, 0, Math.abs(delta) * 2);
		invalidate();
	}

	protected void snapToDestination() {
		if (getScrollX() == 0) {
			return;
		}
		final int screenWidth = getChildAt(0).getWidth();
		final int whichScreen = (screenWidth + getScrollX() + (screenWidth / 2))
				/ screenWidth;
		snapToScreen(whichScreen);
	}

	public int getCurrentScreen() {
		return mCurrentScreen;
	}

	public boolean isMainScreenShowing() {
		return mCurrentScreen == SCREEN_MAIN;
	}

	public void openMenu() {
		mCurrentScreen = SCREEN_MENU;
		snapToScreen(mCurrentScreen);
	}

	public void closeMenu() {
		mCurrentScreen = SCREEN_MAIN;
		snapToScreen(mCurrentScreen);
	}

	public void unlock() {
		mLocked = false;
	}

	public void lock() {
		mLocked = true;
	}

}

  

原文详情地址:http://git.oschina.net/zzunet/wemall-doraemon/commit/e8f303df5663dc69fe47bb9623222149d40e3956

wemall doraemonAndroid app商城详情地址:http://www.koahub.com/home/product/55

wemall官网地址:http://www.wemallshop.com

wemall 开源微商城 ,微信商城,商城源码,三级分销,微生鲜,微水果,微外卖,微订餐---专业的o2o系统

 
 

wemall doraemon中Android app商城系统解决左侧抽屉菜单和viewpager不能兼容问题的更多相关文章

  1. wemall doraemon中Android app商城系统工具集合类,包含各种程序中用到的静态方法

    wemall doraemon中Android app商城系统工具集合类,包含各种程序中用到的静态方法,可用于其他商城或者系统的编程参考 package cn.zzu.edu.wemall.utils ...

  2. wemall doraemon中Android app商城系统向指定URL发送GET方法的请求代码

    URL的openConnection()方法将返回一个URLConnection对象,该对象表示应用程序和 URL 之间的通信链接.程序可以通过URLConnection实例向该URL发送请求.读取U ...

  3. wemall app商城系统Android之支付宝接口RSA函数

    wemall-mobile是基于WeMall的Android app商城,只需要在原商城目录下上传接口文件即可完成服务端的配置,客户端可定制修改.本文分享支付宝接口RSA函数,RSA签名.验签.解密等 ...

  4. Android APP使用系统签名

    Android M平台在写APP测试使用MediaRecoder通过AudioSource.VOICE_CALL来录制通话上下行音的时候,需要权限 <uses-permission androi ...

  5. Android app作为系统应用实现功能笔记

    1.禁用StatusBar相关功能需要添加权限 <uses-permission android:name="android.permission.STATUS_BAR"&g ...

  6. android 5.X Toolbar+DrawerLayout实现抽屉菜单

    前言  android5.X新增的一个控件Toolbar,这个控件比ActionBar更加自由,可控,因为曾经的ActionBar的灵活性比較差,所以google逐渐使用Toolbar替代Action ...

  7. Android app被系统kill的场景

    何时发生 当我们的app被切到后台的时候,比如用户按下了home键或者切换到了别的应用,总之是我们的app不再和用户交互了,这个时候对于我们的app来说就是什么事情都可能发生的时候了,因为系统会认为你 ...

  8. Winform中实现仿XP系统的任务栏菜单效果(附代码下载)

    场景 效果 注: 博客主页: https://blog.csdn.net/badao_liumang_qizhi 关注公众号 霸道的程序猿 获取编程相关电子书.教程推送与免费下载. 实现 新建一个Fo ...

  9. wemall app商城源码中基于JAVA的Android异步加载图片管理器代码

    wemall doraemon是Android客户端程序,服务端采用wemall微信商城,不对原商城做任何修改,只需要在原商城目录下上传接口文件即可完成服务端的配置,客户端可随意定制修改.本文分享其中 ...

随机推荐

  1. 解决NetStream.appendBytes直播爆音的问题解决

    研究了一下Adobe家HDS的具体实现 OSMF.利用其中的一个核心方法 flash.net.NetStream.appendBytes()构建了我们自己的HTTP点直播播放框架.但今年年初发现一个问 ...

  2. Java线程:线程安全类和Callable与Future(有返回值的线程)

    一.线程安全类 当一个类已经很好的同步以保护它的数据时,这个类就称为线程安全的.当一个集合是安全的,有两个线程在操作同一个集合对象,当第一个线程查询集合非空后,删除集合中所有元素的时候,第二个线程也来 ...

  3. 支付宝开发中return_url和notify_url的区别分析

    在处理支付宝业务中出现过这样的问题,付费完成后,在支付宝跳转到商家指定页面时,订单状态已经更新,通过调试发现是支付宝先通知notify_url,完成了订单状态. 支付宝return_url和notif ...

  4. I帧/P帧/B帧---术语解释

    视频压缩中,每帧代表一幅静止的图像.而在实际压缩时,会采取各种算法减少数据的容量,其中IPB就是最常见的.  简单地说,I帧是关键帧,属于帧内压缩.就是和AVI的压缩是一样的. P是向前搜索的意思.B ...

  5. 【java设计模式】之 抽象工厂(Abstract Factory)模式

    1. 女娲的失误 上一节学习了工厂模式,女娲运用了该模式成功创建了三个人种,可是问题来了,她发现没有性别--这失误也忒大了点吧--竟然没有性别,那岂不是--无奈,只好抹掉重来了,于是所有人都被消灭掉了 ...

  6. shift、unshift、 push、pop用法--JavaScript参考手册

    转自http://www.blogbus.com/kingslay-logs/216353709.html shift()定义和用法shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元 ...

  7. 前端基本知识(二):JS的原始链的理解

    之前一直对于前端的基本知识不是了解很详细,基本功不扎实,但是前端开发中的基本知识才是以后职业发展的根基,虽然自己总是以一种实践是检验真理的唯一标准,写代码实践项目才是唯一,但是经常遇到知道怎么去解决这 ...

  8. CoreData和FMDB你用哪个?

    概括: 我们先说说这两个东西,CoreData 和 FMDB,其实就我自己而言觉得这两个都不错,刚开始是接触FMDB的,CoreData是工作后自己看的.苹果推荐开发者去使用CoreData,但 FM ...

  9. 关系型数据库MySql-模糊搜索优化(like %abc%):全文搜索引擎技术选型

    1.阿里云OpenSearch 阿里云开放搜索OpenSearch是一款阿里巴巴自主研发的大规模分布式搜索引擎平台,该平台承载了淘宝.天猫.1688.神马搜索.口碑.菜鸟等搜索业务,通过OpenSea ...

  10. Oracle索引语句整理

    转载:http://www.cnblogs.com/djcsch2001/articles/1823459.html 索引,索引的建立.修改.删除 索引索引是关系数据库中用于存放每一条记录的一种对象, ...