Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 如果寫一個android桌面滑動切換屏幕的控件(三)

如果寫一個android桌面滑動切換屏幕的控件(三)

編輯:關於Android編程

下面我們把這個控件內嵌到Layout中做一些動畫和展示,效果圖:

\


這個子控件可以上下移動,可以左右滑動,如果上下滑動距離大於左右滑動距離,則必須上下滑動<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+1eLR+cC00LRvblRvdWNoysK8/jo8L3A+CjxwPjxwcmUgY2xhc3M9"brush:java;"> @Override public boolean onTouchEvent(MotionEvent ev) { if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } mVelocityTracker.addMovement(ev); int mScrollX = this.getScrollX(); final int action = ev.getAction(); final float x = ev.getX(); final float y = ev.getY(); switch (action) { case MotionEvent.ACTION_DOWN: mFlagLimitMove = false; mFlagLimitUp = false; /* * 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 mOriMotionX = x; mOriMotionY = y; mLastMotionX = x; mLastMotionY = y; mTimeDown = System.currentTimeMillis(); mLastDownX = x; return true; case MotionEvent.ACTION_MOVE: //如果是往後滑動,屏幕向前,那麼mLastMotionX是比x大的,deltaX是正的 int deltaX = (int) (mLastMotionX - x); int deltaY = (int) (mLastMotionY - y); // final int moveX = (int) (mOriMotionX - x); final int moveY = (int) (mOriMotionY - y); mLastMotionX = x; mLastMotionY = y; //X方向的移動更多 if (Math.abs(deltaY) < Math.abs(deltaX)) { //雖然X方向移動更多,但由於已經判定為上下滑動,所以只能return true,做這種情況左右不能滑動 if (mFlagLimitUp) { return true; } final int buffer = getWidth() / 2; if (deltaX < 0) { if (deltaX < -MOVEY_NUM_X) { //mFlagLimitMove代表X方向確認在滑動了 mFlagLimitMove = true; } if (mCurrentScreen == 0 && !mExecuteWhileSnapOut) { System.out.println("=====deltaX="+deltaX); deltaX = getSlowDownDelta(deltaX); System.out.println("=====after deltaX="+deltaX); } System.out.println("====mScrollX="+mScrollX+"buffer="+buffer+"deltaX="+deltaX+"x="+(Math.max(-mScrollX - buffer, deltaX))); scrollBy(Math.max(-mScrollX - buffer, deltaX), 0); // } } else if (deltaX > 0) { int availableToScroll = 0; if (getChildCount() > 0) { //此時Workspace上可能未加任何item,count == 0 availableToScroll = getChildAt( getChildCount() - 1).getRight() - mScrollX - getWidth(); } if (deltaX > MOVEY_NUM_X) { mFlagLimitMove = true; } if (mCurrentScreen == getChildCount() - 1 && !mExecuteWhileSnapOut) { deltaX = getSlowDownDelta(deltaX); } System.out.println("====availableToScroll="+availableToScroll+"deltaX="+deltaX); scrollBy(Math.min(availableToScroll + buffer, deltaX), 0); } } else { //如果已經判定為上下滑動或 ,當時X方向也有移動,這種情況也不處理 if (mFlagLimitMove || mFlagLimitUp) { return true; } //deltaY>0說明為往上滑動 if (deltaY > 0 && moveY > MOVEY_NUM) { if (mHandler != null) { mFlagLimitUp = true; mHandler.sendMessage(mHandler .obtainMessage(DingLayout.MESSAGE_MOVING_UP)); } } else if (deltaY < 0 && moveY < -MOVEY_NUM) { if (mHandler != null) { mFlagLimitUp = true; mHandler.sendMessage(mHandler .obtainMessage(DingLayout.MESSAGE_MOVING_DOWN)); } } } return true; case MotionEvent.ACTION_UP: final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(DEFAULT_VALUE, mMaximumVelocity); int velocityX = (int) velocityTracker.getXVelocity(); int velocityY = (int) velocityTracker.getYVelocity(); System.out.println("====mFlagLimitUp="+mFlagLimitUp+"mFlagLimitMove="+mFlagLimitMove); if (!mFlagLimitUp) { if (velocityX > SNAP_VELOCITY && mCurrentScreen > 0) { // Fling hard enough to move left snapToScreen(mCurrentScreen - 1); } else if (velocityX < -SNAP_VELOCITY && mCurrentScreen < getChildCount() - 1) { // Fling hard enough to move right snapToScreen(mCurrentScreen + 1); } else { snapToDestination(mLastMotionX < mOriMotionX); } } else { snapToDestination(mLastMotionX < mOriMotionX); } mTimeUp = System.currentTimeMillis(); //如果x方向移動非常少,並且沒有y方向的移動,我們來判斷是不是點擊事件 if (!mFlagLimitUp && !mFlagLimitMove) { // 如果點擊時間比較短,而且手指沒有移動很大位置,則認為為點擊事件 if (Math.abs(x - mOriMotionX) < MOVE_LIMIT && Math.abs(y - mOriMotionY) < MOVE_LIMIT && Math.abs(mTimeUp - mTimeDown) < TIME_LIMIT) { if (mHandler != null) { mHandler.sendMessage(mHandler.obtainMessage( DingLayout.MESSAGE_MOVING_CLICK, y)); return true; } } if (velocityY > Y_RATE_LIMIT && Math.abs(velocityX) < X_RATE_LIMIT) { if (mHandler != null) { mHandler.sendMessage(mHandler .obtainMessage(DingLayout.MESSAGE_MOVING_DOWN)); } } else if (velocityY < -Y_RATE_LIMIT && Math.abs(velocityX) < X_RATE_LIMIT) { if (mHandler != null) { mHandler.sendMessage(mHandler .obtainMessage(DingLayout.MESSAGE_MOVING_UP)); } } } // end flag if (mVelocityTracker != null) { mVelocityTracker.recycle(); mVelocityTracker = null; } mFlagLimitMove = false; mFlagLimitUp = false; mTouchState = TOUCH_STATE_REST; if (Math.abs(mLastDownX - x) > TEN) { return true; } return false; case MotionEvent.ACTION_CANCEL: mTouchState = TOUCH_STATE_REST; return false; default: break; } return true; }
activity:

布局:




    

        


        


            

                


                
            
        
    


activity:

public class DingLayoutActivity extends Activity implements
		OnViewChangedListener {

	DingLayout mDingLayout;
	Workspace mWorkspace;
	/** 用inflater來載入layout. */
	private LayoutInflater mInflater;
	int mTotalDingnum;
	ImageView mBtnRefresh;
	private int mCurrentDownUrlIndex = 0;

	public Handler mHandler = new Handler() {
		public void handleMessage(Message msg) {

		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.main1);

		mDingLayout = (DingLayout) findViewById(R.id.dinglayout);
		mDingLayout.setHandlerFormActivity(this.mHandler);

		mWorkspace = (Workspace) findViewById(R.id.workspace);
		mWorkspace.setOnViewChangedListener(this);

		initialWorkspace();

	}

	/**
	 * 初始化workspace.
	 */
	private void initialWorkspace() {

		mInflater = LayoutInflater.from(this);
		// 該list為內存中的ding列表,列表中元素存儲著ding的A部分數據
		DingManager dingMgr = DingManager.getInstance(this);
		List list = dingMgr.getDingList();
		mTotalDingnum = list.size();

		// 遍歷列表中的各個元素來構造workspace中的view
		for (int i = 0; i < mTotalDingnum; i++) {
			View view = mInflater.inflate(R.layout.ding_item, null);

			DingInfo info = list.get(i);
			view.setTag(info.getDingId());

			String oldContent = info.getContent();

			mWorkspace.addView(view);

			mBtnRefresh = (ImageView) view.findViewById(R.id.btn_refresh);
			setViewData(info, view, true);

			info.setContent(oldContent);
			// end modify
		}

		mDingLayout.updateDots(mTotalDingnum, mCurrentDownUrlIndex);
	}

	private void setViewData(DingInfo netdingdata, View view, boolean useTitle) {
		if (view == null) {
			return;
		}

		TextView title = (TextView) view.findViewById(R.id.title);
		TextView content = (TextView) view.findViewById(R.id.main_content);
		TextView description = (TextView) view.findViewById(R.id.description);
		TextView time = (TextView) view.findViewById(R.id.time);
		title.setText(netdingdata.getTitle());
		// 默認值如果為空,不更新
		String updateContent = netdingdata.getContent();
		if (!TextUtils.isEmpty(updateContent)) {
			// modify by qiaopu 用title的view
			if (useTitle) {
				title.setText(netdingdata.getContent());
				content.setText("");
			} else {
				content.setText(netdingdata.getContent());
			}
			// end modify
		}

		description.setText(netdingdata.getDescription());
		time.setText(netdingdata.getTime());

	}

	@Override
	public void onViewChanged(int viewIndex) {
		if (viewIndex < 0 || viewIndex >= mTotalDingnum) {
			// Log.d(TAG, "invalid mCurrentDownUrlIndex");
			return;
		}

		if (mCurrentDownUrlIndex != viewIndex) {
			View view = mWorkspace.getChildAt(mCurrentDownUrlIndex);
			if (view != null) {
			}

			mCurrentDownUrlIndex = viewIndex;
			mDingLayout.updateDots(mTotalDingnum, mCurrentDownUrlIndex);

		}

	}

}

DingLayout:

public class DingLayout extends RelativeLayout {
//	/** Context */
//	private Context mContext;

	/** MESSAGE_MOVING_UP表示手勢的動作為向上滑. */
	public static final int MESSAGE_MOVING_UP = 0;

	/** MESSAGE_MOVING_UP表示手勢的動作為向下滑. */
	public static final int MESSAGE_MOVING_DOWN = 1;

	/** MESSAGE_MOVING_UP表示手勢的動作為點擊. */
	public static final int MESSAGE_MOVING_CLICK = 2;

	/** isUp為判斷workspace是否在上方. */
	private boolean mIsUp = false;

	/** isUp為判斷滑動的動畫是否在進行中. */
	private boolean mIsMove = false;

	/** 可上下滑動的Layout,包括Workspace和點點提示。 */
	private ViewGroup mUpDownLayout;
	/** Workspace. */
	private Workspace mSpace;
	/** 點點提示Workspace當前頁的Layout。 */
	private LinearLayout mDotsLayout;
    /** 點點的Y坐標偏移。由於點點需要顯示在DING圖標下面,而DING圖標只有在Workspace的screen中才有,所以用此全局來計算並記住。 */
	private int mDotsOffsetY;
	/** 當前索引。 */
	private int mCurrent = -1;
    
	/** log tag. */
	private static final String TAG = "DingLayout";


	/** 動畫運行時間. */
	private static final int ANIMATIONTIME = 650;

	/** mHandlerFromMainActivity從main activity傳進來. */
	private Handler mHandlerFromMainActivity;

	/** 是否是動畫進行中.*/
	private boolean isRunning = false;
	
	/** Context*/
	private Context mContext = null;
	
	/**
	 * view的構造函數.
	 * 
	 * @param context
	 *            context
	 * @param attrs
	 *            attrs
	 * 
	 */
	public DingLayout(Context context, AttributeSet attrs) {
		super(context, attrs);
		mIsUp = false;
		isRunning = false;
		mContext = context;
	}

	/**
	 * @return 為ding在上還是在底下的標識
	 */
	public boolean isUp() {
		return mIsUp;
	}

	/**
	 * 把mainActivity的hander傳入這個view.
	 * @param handlerFromMainActivity HandlerFromMainActivity           
	 */
	public void setHandlerFormActivity(Handler handlerFromMainActivity) {
		this.mHandlerFromMainActivity = handlerFromMainActivity;
	}

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        //如果在動畫進行中,不進行event的分發
        if (isRunning) {
            return true;
        }
        return super.dispatchTouchEvent(ev);
    }

	
    @Override
    protected void onLayout(boolean changed, int left, int top, int right,
            int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        //下面兩句保證初始化時workspace的位置在上面或是在下面
        if (mIsUp) {
            layoutUp();
        } else {
            layoutDown();
        }
        
        if (mDotsOffsetY == 0) {
            View dingView = findViewById(R.id.ding_view);
            if (dingView != null) {
                mDotsOffsetY = dingView.getBottom();
                System.out.println("=====mDotsOffsetY="+mDotsOffsetY);
            }
        }
        
        if (mDotsOffsetY > 0) {
            //需要修改LayoutParams,否則在parent調用Layout的時候,坐標又會被改變。
            LayoutParams params = (LayoutParams) mDotsLayout.getLayoutParams();
            params.topMargin += mDotsOffsetY;
            mDotsLayout.layout(mDotsLayout.getLeft(), 
                    mDotsLayout.getTop() + mDotsOffsetY, 
                    mDotsLayout.getRight(), 
                    mDotsLayout.getBottom() + mDotsOffsetY);
            
            //只需執行一次。
            mDotsOffsetY = -1;
        }
    }

	@Override
	protected void onFinishInflate() {
		super.onFinishInflate();
		
		mUpDownLayout = (ViewGroup) findViewById(R.id.ding_updown_layout);
		
		mSpace = (Workspace) findViewById(R.id.workspace);
		mSpace.setHandler(mHandler);
		//
		
		mDotsLayout = (LinearLayout) findViewById(R.id.dots_layout);
	}
	
	/**
	 * 更新點點的狀態,包括總數和當前位置。
	 * @param total 總數。
	 * @param current 當前位置。
	 */
	public void updateDots(int total, int current) {
	    Workspace.updateDots(mDotsLayout, total, current, null);
	}

	/**
     * setCurrentScreen.
     * @param index Index.
     */
    public void setCurrentScreen(int index) {
        mSpace.setCurrentScreen(index);
        updateDots(getDingCount(), index);
    }
      
	/**
	 * set IsUp的值.
	 * @param isUp  set mIsUp值          
	 */
	public void setIsUp(boolean isUp) {
		this.mIsUp = isUp;
	}
	
	/**
	 * 獲取Ding的數量。
	 * @return 數量。
	 */
	private int getDingCount() {
	    List list = DingManager.getInstance(getContext())
                .getDingList();
        return list.size();
	}

	/**
	 * 向上移的動畫.
	 */
	private void moveUp() {
        logCat("moveUp mToppanel.getWidth()=" + mUpDownLayout.getWidth()
                    + "mToppanel.getHeight()=" + mUpDownLayout.getHeight());
        layoutUp();
        
        Animation upAnimation = new TranslateAnimation(0, 0,
                getWorkSpaceDownPosition(), 0);
        upAnimation.setDuration(ANIMATIONTIME);
        upAnimation.setAnimationListener(new AnimationListener() {

            @Override
            public void onAnimationStart(Animation animation) {
                mIsMove = true;
                isRunning = true;
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                mIsMove = false;
                isRunning = false;
                if (mHandlerFromMainActivity != null) {
                    Message msg = mHandlerFromMainActivity.obtainMessage();
                    msg.what = SearchListener.MSG_ANIMATION_DONE;
                    mHandlerFromMainActivity.handleMessage(msg);
                    mHandlerFromMainActivity
                            .sendEmptyMessage(SearchListener.MSG_DING_UP_FINISHED);
                    mHandlerFromMainActivity
                            .sendEmptyMessage(SearchListener.MSG_DING_MOVE_UP);
                }
            }
        });
        
        if (mHandlerFromMainActivity != null) {
            Message msg = mHandlerFromMainActivity.obtainMessage();
            msg.what = SearchListener.MSG_ANIMATION_PREPARE;
            mHandlerFromMainActivity.handleMessage(msg);
        }
        mUpDownLayout.startAnimation(upAnimation);
	}

    /**
     * 向下移的動畫.
     */
    private void moveDown() {
        if (mHandlerFromMainActivity != null) {
            //
        }
        
        logCat("mToppanel.getWidth()=" + mUpDownLayout.getWidth()
                + "mToppanel.getHeight()=" + mUpDownLayout.getHeight());
        layoutDown();

        Animation downAnimation = new TranslateAnimation(0, 0,
                -getWorkSpaceDownPosition(), 0);
        downAnimation.setDuration(ANIMATIONTIME);
        downAnimation.setAnimationListener(new AnimationListener() {

            @Override
            public void onAnimationStart(Animation animation) {
                mIsMove = true;
                isRunning = true;
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                mIsMove = false;
                isRunning = false;
                if (mHandlerFromMainActivity != null) {
                    Message msg = mHandlerFromMainActivity.obtainMessage();
                    msg.what = SearchListener.MSG_ANIMATION_DONE;
                    mHandlerFromMainActivity.handleMessage(msg);
                }
            }
        });

        
        if (mHandlerFromMainActivity != null) {
            Message msg = mHandlerFromMainActivity.obtainMessage();
            msg.what = SearchListener.MSG_ANIMATION_PREPARE;
            mHandlerFromMainActivity.handleMessage(msg);
        }
        mUpDownLayout.startAnimation(downAnimation);
    }
    
    /**
     * 上移。
     */
    private void layoutUp() {
        mUpDownLayout.layout(mUpDownLayout.getLeft(), 0, mUpDownLayout.getRight(),
                mUpDownLayout.getHeight());
        mUpDownLayout.setDrawingCacheEnabled(true);
        mUpDownLayout.buildDrawingCache();
    }

    /**
     * 下移。
     */
    private void layoutDown() {
    	
        int workSpacePosition = getWorkSpaceDownPosition();
        mUpDownLayout.layout(mUpDownLayout.getLeft(), workSpacePosition, 
                mUpDownLayout.getRight(), workSpacePosition + mUpDownLayout.getHeight());
        mUpDownLayout.setDrawingCacheEnabled(false);
    }

	/**
	 * 獲取workspace下移後的(top)position。
	 * @return position.
	 */
	private int getWorkSpaceDownPosition() {
		//A部分的高度
	    int heightPartA = getResources().getDimensionPixelSize(R.dimen.browseraddview_height);
        return getHeight() - heightPartA;
	}

    /**
     * 打log用.
     * @param log log           
     */
    private void logCat(String log) {
    }

	/**
	 * 處理動畫的Handler.
	 */
	private Handler mHandler = new Handler() {
		public void handleMessage(Message msg) {
			if (mIsMove) {
				return;
			}
			switch (msg.what) {
			case MESSAGE_MOVING_UP:
				// top.setVisibility(View.GONE);

				if (!mIsUp) {
					mIsUp = true;
					moveUp();
				}
				break;
			case MESSAGE_MOVING_DOWN:
				if (mIsUp) {
					mIsUp = false;
					// if(mHandler_fromActivity != null){
					// mHandler_fromActivity.sendEmptyMessage(SearchListener.MSG_DING_MOVE_DOWN);
					// }
					moveDown();
				}
				break;
			case MESSAGE_MOVING_CLICK:
				Object obj = msg.obj;
				Float t = (Float) obj;

				int dingLayoutHeight = getResources().getDimensionPixelSize(R.dimen.browseraddview_height);
				// t
item的布局:





	

    
    

    
    
    
    
    

    
    
    
	
    
    
	
	
    
    






  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved