Android進(jìn)階之view坐標(biāo)系全面詳解
前言
首先祝大家國慶節(jié)快樂,玩的開心;
一、Android坐標(biāo)系詳解
說到Android坐標(biāo)系其實就是一個三維坐標(biāo),Z軸向上,X軸向右,Y軸向下。這三維坐標(biāo)的點處理就能構(gòu)成Android豐富的界面或者動畫等效果;
1、Android屏幕一些值的獲取
①獲取屏幕區(qū)域的寬高等尺寸獲取
- DisplayMetrics metrics = new DisplayMetrics();
- getWindowManager().getDefaultDisplay().getMetrics(metrics);
- int widthPixels = metrics.widthPixels;
- int heightPixels = metrics.heightPixels;
②應(yīng)用程序App區(qū)域?qū)捀叩瘸叽绔@取
- Rect rect = new Rect();
- getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
③獲取狀態(tài)欄高度
- Rect rect= new Rect();
- getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
- int statusBarHeight = rectangle.top;
④View布局區(qū)域?qū)捀叩瘸叽绔@取
- Rect rect = new Rect();
- getWindow().findViewById(Window.ID_ANDROID_CONTENT).getDrawingRect(rect);
2、Android View絕對相對坐標(biāo)系
View的靜態(tài)坐標(biāo)方法
- getLeft():返回View自身左邊到父布局左邊的距離;
- getTop():返回View自身頂邊到父布局頂邊的距離;
- getRight():返回View自身右邊到父布局左邊的距離;
- getBottom():返回View自身底邊到父布局頂邊的距離;
- getX():返回值為getLeft()+getTranslationX(),當(dāng)setTranslationX()時getLeft()不變,getX()變;
- getY():返回值為getTop()+getTranslationY(),當(dāng)setTranslationY()時getTop()不變,getY()變;
3、手指觸摸屏幕時MotionEvent提供的一些方法
- getX():當(dāng)前觸摸事件距離當(dāng)前View左邊的距離
- getY():當(dāng)前觸摸事件距離當(dāng)前View頂邊的距離
- getRawX():當(dāng)前觸摸事件距離整個屏幕左邊的距離
- getRawY():當(dāng)前觸摸事件距離整個屏幕頂邊的距離
4、View寬高方法
- getWidth()layout后有效,返回值是mRight-mLeft;
- getHeight()layout后有效,返回值是mBottom-mTop;
- getMeasuredWidth()返回measure過程得到的mMeasuredWidth值;
- getMeasuredHeight()返回measure過程得到的mMeasuredHeight值;
5、Android View滑動相關(guān)坐標(biāo)系
View的滑動方法
- offsetLeftAndRight(int offset)|水平方向挪動View,offset為正則x軸正向移動,移動的是整個View,getLeft()會變的,自定義View很有用;
- offsetTopAndBottom(int offset)|垂直方向挪動View,offset為正則y軸正向移動,移動的是整個View,getTop()會變的,自定義View很有用;
- scrollTo(int x, int y)|將View中內(nèi)容(不是整個View)滑動到相應(yīng)的位置,參考坐標(biāo)原點為ParentView左上角,x,y為正則向xy軸反方向移動,反之同理;
- scrollBy(int x, int y)|在scrollTo()的基礎(chǔ)上繼續(xù)滑動xy。
- setScrollX(int value)|實質(zhì)為scrollTo(),只是只改變Y軸滑動。
- setScrollY(int value)|實質(zhì)為scrollTo(),只是只改變X軸滑動。
- getScrollX()/getScrollY()|獲取當(dāng)前滑動位置偏移量。
關(guān)于Android View的scrollBy()和scrollTo()參數(shù)傳遞正數(shù)卻向坐標(biāo)系負(fù)方向移動的特性可能很多人都有疑惑,甚至是死記結(jié)論,這里我們簡單給出產(chǎn)生這種特性的真實原因—-源碼分析,如下:
- public void scrollTo(int x, int y) {
- if (mScrollX != x || mScrollY != y) {
- int oldX = mScrollX;
- int oldY = mScrollY;
- mScrollX = x;
- mScrollY = y;
- invalidateParentCaches();
- onScrollChanged(mScrollX, mScrollY, oldX, oldY);
- if (!awakenScrollBars()) {
- postInvalidateOnAnimation();
- }
- }
- }
View的該方法注釋里明確說明了調(diào)運他會觸發(fā)onScrollChanged()和invalidated()方法,那我們就將矛頭轉(zhuǎn)向invalidated()方法觸發(fā)的draw()過程,draw()過程中最終其實會觸發(fā)下面的invalidate()方法,如下:
- public void invalidate(int l, int t, int r, int b) {
- final int scrollX = mScrollX;
- final int scrollY = mScrollY;
- //scroller時為何參數(shù)和坐標(biāo)反向的真實原因
- invalidateInternal(l - scrollX, t - scrollY, r - scrollX, b - scrollY, true, false);
- }
核心就在這里
scrollTo()和scrollBy()方法特別注意:如果你給一個ViewGroup調(diào)用scrollTo()方法滾動的是ViewGroup里面的內(nèi)容,如果想滾動一個ViewGroup則再給他嵌套一個外層,滾動外層即可
總結(jié)
- view獲取自身坐標(biāo):getLeft(),getTop(),getRight(),getBottom()
- view獲取自身寬高:getHeight(),getWidth()
- motionEvent獲取坐標(biāo):getX(),getY(),getRawX(),getRawY()
- 然后是motionEvent的方法:
- getX():獲取點擊事件相對控件左邊的x軸坐標(biāo),即點擊事件距離控件左邊的距離
- getY():獲取點擊事件相對控件頂邊的y軸坐標(biāo),即點擊事件距離控件頂邊的距離
- getRawX():獲取點擊事件相對整個屏幕左邊的x軸坐標(biāo),即點擊事件距離整個屏幕左邊的距離
- getRawY():獲取點擊事件相對整個屏幕頂邊的y軸坐標(biāo),即點擊事件距離整個屏幕頂邊的距離