什麼是view
view是android中所有控件的基類,例如textview,button或者viewgroup等。viewgroup也繼承了view,但是可以包含多個控件。
這是我網上找的一張繼承關係圖:
view的參數
view最基礎的四個參數 left,top,right,bottom,通過view的
getLeft(),
getTop(),
getRight(),
getBottom()方法獲取。分別代表左上角橫座標,左上角縱座標,右上角橫座標,右上角縱座標。需要注意的是這些座標是相對座標,相對於自己這個view的父容器。在android中x軸和y軸的正方向代表的是右邊和下邊,屏幕左上角爲起點向右和下x,y增大。根據這個view的寬和高也很容易計算出:
width = rigth-left
heigth = bottom-top
從android3.0開始,view增加了幾個參數,分別是x,y,translationX,translationY。translationX和translationY代表的是view的偏移量。偏移後left,top這些值不會改變,改變的是x,y,translationX,translationY。所以可以得到這幾個位置參數之間的關係:
x = left + translationX
y = top + translationY
view可以通過getX()和getY()方法獲取x和y的值,x和y同樣是相對座標。如果想獲取相對於手機屏幕左上角的座標,可以使用getRawX()和getRawY()方法來獲取。
view的滑動
view的滑動有很多種方式,這裏舉幾種常見的來說。
通過scrollTo/scrollBy:它可以快速的實現view的滑動效果。但是要注意的是滑動的只是view的內容,並不是view本身。例如一個button修改了scrollX,移動的只是button裏的字,button本身並不會移動,類似於listview中item的移動。從源碼可以看出scrollBy調用的就是scrollTo方法,顧名思義,scrollBy代表的是相對滑動,scrollTo代表的是絕對滑動。要注意的是內容向右邊移動mScrollX是負的,向左邊移動mScrollX爲正,mScrollY也是如此,內容向下爲負,向上爲正。
Scroller scroller = new Scroller(context);
scroller.startScroll(getScrollX(),0,-100,0,2000);
invalidate();
使用scroller來實現滑動,startScroll方法傳入滑動的起點和要滑動的距離,然後還有滑動的時間。
當然這樣並不會讓view開始滑動。查看源碼可以發現它只是保存了我們傳入的參數:
public void startScroll(int startX, int startY, int dx, int dy, int duration) {
mMode = SCROLL_MODE;
mFinished = false;
mDuration = duration;
mStartTime = AnimationUtils.currentAnimationTimeMillis();
mStartX = startX;
mStartY = startY;
mFinalX = startX + dx;
mFinalY = startY + dy;
mDeltaX = dx;
mDeltaY = dy;
mDurationReciprocal = 1.0f / (float) mDuration;
}
關鍵在於invalidate方法,它會導致view的重繪,然後在view的draw()方法中又會調用computeScroll()方法,由於computeScroll是一個空實現,所以需要我們自己去實現:
public void computeScroll(){
if(mScroller.computeScrollOffset()){
scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
postInvalidate();
}
}
裏面做了一些判斷是否需要繼續滑動。如果需要滑動就會調用postInvalidate()導致重繪,如此反覆直到滑動結束。
view的滑動當然也可以通過動畫來實現。需要注意的是,普通動畫移動後實際上view並沒有移動,例如一個button移動了你會發現點擊無效。點擊原來的位置有效。不過屬性動畫可以解決這個問題。
view的滑動也可以通過layoutParams來實現。逐漸增大margin。