wemall doraemon中Android app商城系统解决左侧抽屉菜单和viewpager不能兼容问题

作者: wemallshop 2016-11-10 16:53:01
完美解决左侧抽屉菜单和viewpager不能兼容左右滑动的问题,可进行参考。
WeMall-Client/res/layout/wemall_main_ui.xml[code]




\ No newline at end of file[/code]WeMall-Client/src/cn/edu/zzu/wemall/ui/MainUIMain.java[code]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>();
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 {

}
}
[/code]WeMall-Client/src/cn/edu/zzu/wemall/ui/SlideMenu.java[code]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;
}

}[/code]原文详情地址: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系统

相关资讯