Android自定義View入門

之前對(duì)自定義View總是有很多的畏懼钧嘶,不知道從什么地方入手乐疆,近期感覺不能再這樣一直使用別人的代碼了筋夏,要試著自己去真正的了解一下Android的底層了扑眉。所以買來任教主的《Android開發(fā)藝術(shù)探索》脑奠,仔細(xì)一讀還真有收獲基公。

現(xiàn)在記錄下來,為跟我一樣的新手提供一些學(xué)習(xí)路上的幫助宋欺。

在我的理解轰豆,自定義View分為以下的幾類:

  1. 繼承View重寫onDraw方法,一般相對(duì)來說比較簡(jiǎn)單齿诞。
  2. 繼承ViewGroup派生出特殊的Layout酸休,這里可以做的更加復(fù)雜。
  3. 繼承自特定的View來實(shí)現(xiàn)的特定的功能

對(duì)于第一種祷杈,相對(duì)來說要比較簡(jiǎn)單斑司,一般就是畫個(gè)圓畫個(gè)方塊之類的,然后復(fù)雜一點(diǎn)可能就要加上動(dòng)畫但汞;第二種宿刮,可以實(shí)現(xiàn)更加復(fù)雜的動(dòng)畫效果,動(dòng)畫之間可能會(huì)有一些比較復(fù)雜的關(guān)聯(lián)之類的私蕾;最后一種僵缺,繼承自某一個(gè)View,例如繼承自一個(gè)Edittext是目,我們可以自己加入一些對(duì)EditText中內(nèi)容的特殊處理谤饭。

今天只說最簡(jiǎn)單的一種:繼承View并實(shí)現(xiàn)動(dòng)畫,以一個(gè)加載等待控件為例,實(shí)現(xiàn)的效果如下

Imgur

STEP 1 編寫一個(gè)類繼承自View懊纳,并重寫構(gòu)造方法

  1. 一般在構(gòu)造方法中揉抵,我們會(huì)抽取出一個(gè)init()方法來進(jìn)行對(duì)View的初始化工作,例如初始化畫筆Paint嗤疯、路徑Path等等冤今,總之哪些只有在第一次創(chuàng)建View的時(shí)候才會(huì)構(gòu)建的參數(shù)都要在這里來初始化。
  2. 一般會(huì)重寫三個(gè)構(gòu)造方法茂缚,這三個(gè)構(gòu)造方法有不同的參數(shù)戏罢,其實(shí)是代表了View不同的初始化方式屋谭,具體如下:
    public LoadingPopPoint(Context context) {        
        super(context);
        //這個(gè)是在java代碼中構(gòu)建的時(shí)候調(diào)用
    }
    
    public LoadingPopPoint(Context context, AttributeSet attrs) {
        super(context, attrs);
        //這個(gè)是在使用xml構(gòu)建的時(shí)候并且沒有指定style的時(shí)候調(diào)用
    }
    
    public LoadingPopPoint(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //這是指定了style的時(shí)候調(diào)用的方法
    }
    

一般都會(huì)在構(gòu)造方法中調(diào)用init來保證初始化的完成

STEP 2 重寫onDraw方法,在onDraw方法中使用canvas繪圖

使用在init方法中初始化的paint對(duì)象龟糕,來繪制圖形桐磁,其實(shí)動(dòng)畫的原理就和老式的電影放映是一樣的,一幀一幀地刷新就好讲岁,其實(shí)就是在onDraw方法中不停的隔一段時(shí)間就重畫一下我擂。這時(shí)就要postInvalidateDelayed(50)這個(gè)方法登場(chǎng)了,這個(gè)方法會(huì)每隔指定的時(shí)間來調(diào)用View的invalidate()方法缓艳,最終會(huì)重新調(diào)用onDraw方法校摩,完成一個(gè)周期,所以如果想控制動(dòng)畫阶淘,我們就可以定義一個(gè)全局的progress變量衙吩,在onDraw方法中不斷的遞增,然后繪制圖形的時(shí)候根據(jù)這個(gè)progress來做出相應(yīng)的調(diào)整溪窒,圖形不就動(dòng)起來了嗎坤塞?

好了,上代碼:

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        for (int i = 0; i < pointNumber; i++) {
            progress[i] = progress[i] + STEP;
            radius = getRadiusByProgress(progress[i]);
            canvas.drawCircle((float) (getWidth() / 2 + x), getHeight() / 2, radius, paints.get(i));
        }
        //redraw the view per 40 milliseconds ,and show the animation
        postInvalidateDelayed(40);
    }

這里的這個(gè)getRadiusByProgress方法中做了一些數(shù)學(xué)的計(jì)算澈蚌,計(jì)算了應(yīng)該在什么地方畫圓尺锚,以及這個(gè)圓的半徑之類的信息,而這里正是這個(gè)View的核心部分惜浅,真心感覺數(shù)學(xué)很重要啊。伏嗜。坛悉。。這個(gè)算法想了好半天才想明白承绸。裸影。。

其實(shí)那些比較炫酷的View動(dòng)畫的實(shí)現(xiàn)军熏,后面都有很強(qiáng)大的算法在做支撐轩猩,總結(jié)起來其實(shí)就是:

一個(gè)好的View動(dòng)畫=強(qiáng)大的算法+對(duì)Android系統(tǒng)API的熟練應(yīng)用

個(gè)人感覺這個(gè)是新手入門的比較不錯(cuò)的例子,好了荡澎,代碼是最好的老師均践,有什么問題看代碼咯 GitHub地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市摩幔,隨后出現(xiàn)的幾起案子彤委,更是在濱河造成了極大的恐慌,老刑警劉巖或衡,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件焦影,死亡現(xiàn)場(chǎng)離奇詭異车遂,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)斯辰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門舶担,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人彬呻,你說我怎么就攤上這事衣陶。” “怎么了废岂?”我有些...
    開封第一講書人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵祖搓,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我湖苞,道長(zhǎng)拯欧,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任财骨,我火速辦了婚禮镐作,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘隆箩。我一直安慰自己该贾,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開白布捌臊。 她就那樣靜靜地躺著杨蛋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪理澎。 梳的紋絲不亂的頭發(fā)上逞力,一...
    開封第一講書人閱讀 49,741評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音糠爬,去河邊找鬼寇荧。 笑死,一個(gè)胖子當(dāng)著我的面吹牛执隧,可吹牛的內(nèi)容都是我干的揩抡。 我是一名探鬼主播,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼镀琉,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼峦嗤!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起屋摔,我...
    開封第一講書人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤寻仗,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后凡壤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體署尤,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡耙替,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了曹体。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片俗扇。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖箕别,靈堂內(nèi)的尸體忽然破棺而出铜幽,到底是詐尸還是另有隱情,我是刑警寧澤串稀,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布除抛,位于F島的核電站,受9級(jí)特大地震影響母截,放射性物質(zhì)發(fā)生泄漏到忽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一清寇、第九天 我趴在偏房一處隱蔽的房頂上張望喘漏。 院中可真熱鬧,春花似錦华烟、人聲如沸翩迈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽负饲。三九已至,卻和暖如春喂链,著一層夾襖步出監(jiān)牢的瞬間绽族,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來泰國(guó)打工衩藤, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人涛漂。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓赏表,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親匈仗。 傳聞我的和親對(duì)象是個(gè)殘疾皇子瓢剿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

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

  • 前言 在Android應(yīng)用開發(fā)過程中,固定的一些控件和屬性可能滿足不了開發(fā)的需求悠轩,所以在一些特殊情況下间狂,我們需要自...
    空空大師丶閱讀 844評(píng)論 0 3
  • 概述 自定義View是Android程序員在進(jìn)階階段是必須經(jīng)歷的也是痛苦的,但是它也沒有想象的那么麻煩火架,無非也就是...
    吳唐人閱讀 214評(píng)論 0 1
  • 前幾天 Ui 突然給我一個(gè) gif 圖說要把這個(gè)做成啟動(dòng)動(dòng)畫,看到效果圖的我表示一臉懵逼纺弊。 好吧牛欢,懵逼歸懵逼,效果...
    Anonymous___閱讀 20,467評(píng)論 93 269
  • 百二秦關(guān)終屬楚淆游,三千越甲當(dāng)吞吳傍睹。 一春播盡萬千種,靜待秋實(shí)果成熟犹菱。
    掌塵閱讀 488評(píng)論 0 1
  • 最近看到一些喜歡的插畫作品拾稳,其中不同的風(fēng)格中有不同側(cè)重的畫面表現(xiàn)方法。現(xiàn)結(jié)合具體作品腊脱,談?wù)劗嬅嬷械摹凹?xì)節(jié)”與“節(jié)奏...
    霖霖加七閱讀 521評(píng)論 0 1