zoukankan      html  css  js  c++  java
  • 菜单栏设置高仿QQHD mini左右滑动菜单栏效果Strut2教程java教程

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

        首先来看看几张果效图:

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

        

        

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

        

        

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

        

        

        上面让我们来看看最主要的那个自定义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”也是免不了的了,
      不过我从不搞“轮巡”,也不会“捕获异常”,更不会“程序异常”,因为我有理性
    克制的。  

  • 相关阅读:
    php中的一些需要注意点
    提权以及反弹shell一些方法
    SVN源码泄露漏洞
    网易白帽子视频的一些笔记
    sql注入的一些笔记
    URL中的"#"、"?"、"&"号的作用
    Asp.net mvc基础(十五)EF原理及SQL监控
    Asp.net mvc基础(十四)Entity Framework
    Asp.net mvc基础(十三)集合常用的扩展方法和Linq语句
    Linux运维基础(二)网络常见问题
  • 原文地址:https://www.cnblogs.com/xinyuyuanm/p/3053735.html
Copyright © 2011-2022 走看看