菜单栏设置高仿QQHD mini左右滑动菜单栏效果Strut2教程-java教程

本文纯属个人见解,是对前面学习的总结,如有描述不正确的地方还请高手指正~

    首先来看看几张果效图:

    1.进入程序时,首先表现间中菜单,即QQHD mini的近来话会列表。

    菜单栏设置高仿QQHD mini左右滑动菜单栏效果Strut2教程-java教程

    

    2.向左滑动,或者点击左上角标图,可以开展边左菜单栏,即QQHD mini的友好列表,有动画果效。

    菜单栏设置高仿QQHD mini左右滑动菜单栏效果Strut2教程-java教程

    

    3.向右滑动或者点击右上角标图,可以开展边右菜单,即QQHD mini的设置之类的布局,这里我放了一个自定义view,作为例子。

    菜单栏设置高仿QQHD mini左右滑动菜单栏效果Strut2教程-java教程

    

    上面让我们来看看最主要的那个自定义view的码源:

    每日一道理
风,渐渐吹起,吹乱了我的发丝,也让我的长裙有些飘动。绿叶仿佛在风中起舞,离开了树,投向了大地,却不知这样会枯萎,我弯下腰,轻轻拾起一片树叶,那非常有序的茎脉,是一种美的点缀。我有些哀叹:绿叶啊,绿叶,你这般美丽地从树上轻轻飘下,随风起舞,却不知已被人称之为落叶!
/**

 * 可阁下切换菜单栏的LinearLayout

 * 

 * @author way

 * 

 */

public class CenterLayout extends LinearLayout {



	private final static String TAG = "CenterLayout";



	public static final int LEFT = 0x001;// 前当表现左菜单栏



	public static final int RIGHT = 0x002;// 前当表现右菜单栏



	public static final int MIDDLE = 0x000;// 前当表现间中主界面



	private int mCurState = MIDDLE;// 前当表现的view



	public final int MENU_border_Width = 50;// 边栏宽度



	private Scroller mScroller;



	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;



	// 3个构造器

	public CenterLayout(Context context, AttributeSet attrs) {

		super(context, attrs);

		initView(context);

	}



	public CenterLayout(Context context) {

		super(context);

		initView(context);

	}



	public Scroller getScroller() {

		return mScroller;

	}



	// 初始化view

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

		mCurState = MIDDLE;// 初始化认默状态

	}



	/**

	 * 取获屏幕宽度

	 * 

	 * @param context

	 * @return

	 */

	private int getViewWidthInPix(Context context) {

		int viewWidthInPix = -1;

		if (viewWidthInPix == -1) {

			WindowManager manager = (WindowManager) context

					.getSystemService(Context.WINDOW_SERVICE);

			viewWidthInPix = manager.getDefaultDisplay().getWidth();

		}

		return viewWidthInPix;

	}



	@Override

	protected void onLayout(boolean changed, int left, int top, int right,

			int bottom) {

		super.onLayout(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;

			}

			break;

		}

		case MotionEvent.ACTION_CANCEL:

		case MotionEvent.ACTION_UP:

			mIsBeingDragged = false;

			mActivePointerId = INVALID_POINTER;

			scrollToScreen();

			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消化失落



		case MotionEvent.ACTION_MOVE:

			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);



			// 在滑动中程过,就需要表现新的brotherView,不然表现的还是之前的brotherView,最后松开手时会然突变称新brotherView,影响休会

			if (distanceX < 0 && getScrollX() < 0 && leftLayout != null) {

				setBrotherVisibility(LEFT);

			} else if (distanceX > 0 && getScrollX() > 0 && rightLayout != null) {

				setBrotherVisibility(RIGHT);

			} else {

				setBrotherVisibility(MIDDLE);

			}



			scrollBy((int) distanceX, 0);



			mLastMotionX = x;

			mLastMotionY = y;

			break;



		case MotionEvent.ACTION_UP:

			mIsBeingDragged = false;

			mActivePointerId = INVALID_POINTER;

			scrollToScreen();

			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);

	}



	private void scrollToScreen() {



		int scrollDistance = 0;



		if (Math.abs(getScrollX()) > getWidth() / 2)

			scrollDistance = (getScrollX() > 0) ? getWidth() - menuWidth

					- getScrollX() : -(getWidth() - menuWidth - Math

					.abs(getScrollX()));

		else

			scrollDistance = -getScrollX();



		int distance = scrollDistance + getScrollX();

		Log.i(TAG, " distance = " + distance);

		if (distance > 0) {

			mCurState = RIGHT;

		} else if (distance < 0) {

			mCurState = LEFT;

		} else {

			mCurState = MIDDLE;

		}

		mScroller.startScroll(getScrollX(), 0, scrollDistance, 0,

				Math.abs(scrollDistance) * 2);

		invalidate();



	}



	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,

			float velocityY) {

		if (Math.abs(velocityX) > ViewConfiguration.get(context)

				.getScaledMinimumFlingVelocity()) {

			fling = true;

			scrollToScreen();

		}



		return fling;

	}



	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;

	}



	/**

	 * 设置前当表现的view

	 * 

	 * @param whichpg

	 */

	public void setPage(int whichpg) {

		int targetX = 0, moveDistance = 0;



		if (whichpg == LEFT) {

			targetX = -(getViewWidthInPix(context) - menuWidth);

			mCurState = LEFT;

		} else if (whichpg == RIGHT) {

			targetX = getViewWidthInPix(context) - menuWidth;

			mCurState = RIGHT;

		} else {

			mCurState = MIDDLE;

		}

		setBrotherVisibility(whichpg);

		moveDistance = targetX - getScrollX();

		mScroller.startScroll(getScrollX(), 0, moveDistance, 0,

				Math.abs(moveDistance) * 2);

		invalidate();

	}



	/**

	 * 返回前当表现的view

	 * 

	 * @return

	 */

	public int getPage() {

		return mCurState;

	}



	public void addChildView(View child) {

		this.childLayout.addView(child);

	}



	/**

	 * 设置BrotherView

	 * 

	 * @param left

	 * @param right

	 */

	public void setBrotherLayout(LinearLayout left, LinearLayout right) {

		this.leftLayout = left;

		this.rightLayout = right;

	}



	/**

	 * 根据前当状态表现或隐藏view

	 * 

	 * @param state

	 */

	private void setBrotherVisibility(int state) {

		switch (state) {

		case LEFT:

			rightLayout.setVisibility(View.GONE);

			leftLayout.setVisibility(View.VISIBLE);

			break;

		case RIGHT:

			rightLayout.setVisibility(View.VISIBLE);

			leftLayout.setVisibility(View.GONE);

			break;

		case MIDDLE:

			break;

		default:

			break;

		}

	}

}

    好了,稍后为大家贴出整完的码源。

    

文章结束给大家分享下程序员的一些笑话语录: 程序员喝酒
  我偶尔采用“木马策略”、“交叉测试”,时间不长就开始“频繁分配释放资源”,“cache”也是免不了的了,
  不过我从不搞“轮巡”,也不会“捕获异常”,更不会“程序异常”,因为我有理性
克制的。  

你可能感兴趣的:(java教程)