Android-控件框架县好、View的分發(fā)機(jī)制和自定義View

看了一天的書构哺,再在網(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ī)制思維導(dǎo)圖
  • 過程邏輯


    View的事件分發(fā)機(jī)制過程邏輯

自定義View

  • 思維導(dǎo)圖


    自定義View思維導(dǎo)圖
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末捣辆,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子此迅,更是在濱河造成了極大的恐慌汽畴,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,599評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件耸序,死亡現(xiàn)場離奇詭異忍些,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)坎怪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,629評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門罢坝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人搅窿,你說我怎么就攤上這事嘁酿∠度” “怎么了?”我有些...
    開封第一講書人閱讀 158,084評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵闹司,是天一觀的道長娱仔。 經(jīng)常有香客問我,道長游桩,這世上最難降的妖魔是什么牲迫? 我笑而不...
    開封第一講書人閱讀 56,708評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮借卧,結(jié)果婚禮上盹憎,老公的妹妹穿的比我還像新娘。我一直安慰自己谓娃,他們只是感情好脚乡,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,813評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著滨达,像睡著了一般奶稠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上捡遍,一...
    開封第一講書人閱讀 50,021評(píng)論 1 291
  • 那天锌订,我揣著相機(jī)與錄音,去河邊找鬼画株。 笑死辆飘,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的谓传。 我是一名探鬼主播蜈项,決...
    沈念sama閱讀 39,120評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼续挟!你這毒婦竟也來了紧卒?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,866評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤诗祸,失蹤者是張志新(化名)和其女友劉穎跑芳,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體直颅,經(jīng)...
    沈念sama閱讀 44,308評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡博个,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,633評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了功偿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片盆佣。...
    茶點(diǎn)故事閱讀 38,768評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出罪塔,到底是詐尸還是另有隱情投蝉,我是刑警寧澤,帶...
    沈念sama閱讀 34,461評(píng)論 4 333
  • 正文 年R本政府宣布征堪,位于F島的核電站瘩缆,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏佃蚜。R本人自食惡果不足惜庸娱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,094評(píng)論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望谐算。 院中可真熱鬧熟尉,春花似錦、人聲如沸洲脂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,850評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽恐锦。三九已至往果,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間一铅,已是汗流浹背陕贮。 一陣腳步聲響...
    開封第一講書人閱讀 32,082評(píng)論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留潘飘,地道東北人肮之。 一個(gè)月前我還...
    沈念sama閱讀 46,571評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像卜录,于是被迫代替她去往敵國和親戈擒。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,666評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容