看了一天的書构哺,再在網(wǎng)上搜了一些知識(shí)點(diǎn),對(duì)View的一些知識(shí)點(diǎn)還是有一些不太清晰的地方熬芜,做了一些筆記
控件框架
控件分成兩類
- ViewGroup控件
- View控件
ViewGroup可以作為父控件包含多個(gè)View莲镣,并管理。上層控件負(fù)責(zé)下層子控件的測量與繪制猛蔽,并傳遞交互事件剥悟。頂層是一個(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:手勢檢測
- onSingleTapUp:單擊
- onFling:快速滑動(dòng)
- onScroll:滑動(dòng)
- onLongPress:長按
- onDoubleTap:雙擊
//首先創(chuàng)建一個(gè)GestureDetector對(duì)象并實(shí)現(xiàn)OnGestureListener或者OnDoubleTapListener接口
GestureDetector mGestureDetector=new GestureDetector(this);
//解決長按屏幕后無法拖動(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)圖