看了一天的書,再在網(wǎng)上搜了一些知識(shí)點(diǎn),對(duì)View的一些知識(shí)點(diǎn)還是有一些不太清晰的地方,做了一些筆記
控件框架
控件分成兩類
- ViewGroup控件
- View控件
ViewGroup可以作為父控件包含多個(gè)View,并管理。上層控件負(fù)責(zé)下層子控件的測(cè)量與繪制,并傳遞交互事件。頂層是一個(gè)ViewParent對(duì)象,所有交互管理事件都由它來統(tǒng)一調(diào)度和分配,從而可以對(duì)整個(gè)視圖進(jìn)行整體控制。
布局
在Activity中使用setContentView()方法來設(shè)置一個(gè)布局,只有調(diào)用該方法布局內(nèi)容才會(huì)顯示出來。
UI界面架構(gòu)圖:
DecorView作為窗口界面的頂層視圖,封裝了一些窗口操作的通用方法。里面所有View的監(jiān)聽事件,都通過WindowManagerService來接收,并通過Activity對(duì)象來回調(diào)相應(yīng)的Listener。
- TitleView是標(biāo)題欄。
- ContentView是一個(gè)Framelayout。
- 設(shè)置requestWindowFeature(Window.FEATURE_NO_TITLE)來設(shè)置隱藏標(biāo)題欄全屏顯示,一定要在setContentView()方法之前調(diào)用才能生效。
在onCreat()方法中調(diào)用setContentView()后,ActivityManagerService會(huì)回調(diào)onResume()方法,此時(shí)系統(tǒng)才會(huì)把整個(gè)DecorView添加進(jìn)PhoneWindow中,并讓其顯示出來,從而最終完成界面的繪制。
View的位置參數(shù)
View的位置由top、left、right、bottom決定,分別對(duì)應(yīng)左上角縱坐標(biāo)、左上角橫坐標(biāo)、右下角橫坐標(biāo)、右下角縱坐標(biāo)。坐標(biāo)是相對(duì)與父容器來說。
從3.0開始,增加了幾個(gè)參數(shù)
x、y、translationX、translationY,分別對(duì)應(yīng)View左上角坐標(biāo)和View的左上角相對(duì)于父容器的偏移量。
x=left+translationX
y=top+translationY
View在平移的過程中,top和left表示的是原始左上角的位置信息,其值不會(huì)發(fā)生改變,此時(shí)改變的是x、y、translationX、translationY。(這就是為什么View的動(dòng)畫執(zhí)行后真身還在原來的地方的原因)
View的事件體系
幾個(gè)對(duì)象
- MotionEvent:手指接觸屏幕后所產(chǎn)生的一系列事件
- ACTION_DOWN:手指剛接觸屏幕
- ACTION_MOVE:手指在屏幕上移動(dòng)
- ACTION_UP:手指從屏幕松開的一瞬間
- 幾個(gè)方法:
- getX/getY:返回相對(duì)于當(dāng)前View左上角的x、y坐標(biāo)
- getRawX/getRawY:返回相對(duì)于手機(jī)屏幕左上角的x、y坐標(biāo)
- TouchSlop:是系統(tǒng)所能識(shí)別出的被認(rèn)為是滑動(dòng)的最小距離,是一個(gè)常量,和設(shè)備有關(guān),不同設(shè)備可能不同
- 獲取這個(gè)常量:ViewConfiguration.get(getContext()).getScaledTouchSlop()
- VelocityTracker:速度追蹤,用于追蹤手指在滑動(dòng)過程的速度,包括水平和豎直方向的速度。
//在View的onTouchEvent方法中追蹤當(dāng)前單擊事件的速度
VelocityTracker velocityTracker=VelocityTracker.obtain();
velocityTracker.addMovement(event);
//想知道當(dāng)前的滑動(dòng)速度
velocityTracker.computeCurrentVelocity(1000);//獲取速度必須先計(jì)算速度,這里指的是1000毫秒內(nèi)的速度
int xVelocityTracker=(int)velocityTracker.getXVelocity();
int yVelocityTracker=(int)velocityTracker.getYVelocity();
//往右滑和往下滑速度是正值,反之則是負(fù)值。
- GestureDetector:手勢(shì)檢測(cè)
- onSingleTapUp:?jiǎn)螕?/li>
- onFling:快速滑動(dòng)
- onScroll:滑動(dòng)
- onLongPress:長(zhǎng)按
- onDoubleTap:雙擊
//首先創(chuàng)建一個(gè)GestureDetector對(duì)象并實(shí)現(xiàn)OnGestureListener或者OnDoubleTapListener接口
GestureDetector mGestureDetector=new GestureDetector(this);
//解決長(zhǎng)按屏幕后無法拖動(dòng)的現(xiàn)象
//托管View的onTouchEvent方法,在方法里添加
boolean consume=mGestureDetector.onTouchEvent(event);
return consume;
- Scroller:彈性滑動(dòng)對(duì)象.Scroller本身無法讓View彈性滑動(dòng),需要VIew和computeScroll配合使用。
//這個(gè)是模版
Scroller scroller=new Scroller(context);
private void smoothScrollTo(int destX,int destY){
int scrollX=getScrollX();
int deltaX=destX-scrollX;//滑動(dòng)的距離
scroller.startScroll(scrollX,0,deltaX,0,1000);
invalidate();//重繪
}
@Override
public void computeScroll(){//重繪會(huì)調(diào)用這個(gè)方法,是空實(shí)現(xiàn),由我們來實(shí)現(xiàn)
if(scroller.computeScrollOffset()){//根據(jù)時(shí)間的流逝和剩下要滑動(dòng)的距離計(jì)算currX的和currY的值,返回true代表滑動(dòng)未完成
scrollerTo(scroller.getCurrX(),scroller.getCurrY());
postInvalidate();//滑動(dòng)未完成,繼續(xù)重繪
}
}
View的滑動(dòng)
- 使用scrollTo/scrollBy
- 使用動(dòng)畫
- 改變布局參數(shù)
View的事件分發(fā)機(jī)制
- 思維導(dǎo)圖

-
過程邏輯
View的事件分發(fā)機(jī)制過程邏輯
自定義View
-
思維導(dǎo)圖
自定義View思維導(dǎo)圖

