1. 程式人生 > >Android-UI控制元件的繪製流程以及自定義控制元件的具體操作

Android-UI控制元件的繪製流程以及自定義控制元件的具體操作

  View檢視安卓應用中非常重要的組成部分,它不僅是構成應用介面的基本單元,還是與使用者互動的最直接物件。檢視View作為介面的基本元素,是由View System進行管理的。

  在Android中,檢視控制元件主要被分成兩大類,一類是單一控制元件View,另外一類是可以包含並管理子控制元件的ViewGroup,在一個介面佈局中,ViewGroup與View的巢狀與組合,就構成了一棵控制元件樹,經過一系列流程繪製在螢幕上,形成完整的使用者介面。

wKiom1jbmsLBfeuYAAAlMr8LoJc710.jpg-wh_50

   View是最基本的UI類,幾乎所有的控制元件都繼承於View,廣義的View指的是除了ViewGroup外的如TextView,CheckBox、Button、EditText、RadioButton等的單一控制元件,它們管理自身的繪製以及對事件的處理。而ViewGroup是View 的子類,同時作為View控制元件的容器而存在,ViewGroup可以控制各個子View 的顯示層次與位置,同時可以對焦點獲取、觸控等互動事件進行處理、攔截或分發。

  檢視的繪製主要分為三個步驟,分別為Measure,Layout跟Draw。

  在Measure操作中,測量的操作的分發由ViewGroup來完成,ViewGroup通過對子節點進行遍歷並分發測量操作,在具體的測量過程中,根據父節點的MeasureSpec以及子節點的LayoutParams等資訊計運算元節點的寬高,最終整理成父容器的寬高,具體的測量方式,我們也可以通過重寫onMeasure方法來設定。

  緊接著,通過Layout過程,來確定每一個View在父容器中的具體位置,同樣的,我們也可以通過onLayout方法來自定義具體的佈局流程。

  最後進入Draw的繪製流程,根據前兩步所獲得的具體佈局引數,在draw函式中對各控制元件進行繪製,繪製的順序為背景-控制元件內容-子控制元件繪製-繪製邊緣以及滾動條等裝飾物。

  總體來說,控制元件的繪製都是在控制元件樹上進行的,由ViewGroup分發給子View各自完成自身的測量與佈局操作,最後由根節點開始進行繪製,最終形成完整的介面。

  最後選擇一個具體的例子來觀察View的繪製流程吧。

  首先我們看一下TextView的具體繪製流程:

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

    int widthMode = MeasureSpec.getMode(widthMeasureSpec);

    int heightMode = MeasureSpec.getMode(heightMeasureSpec);

    int widthSize = MeasureSpec.getSize(widthMeasureSpec);

    int heightSize = MeasureSpec.getSize(heightMeasureSpec);

    int width;

    int height;

    ......

    setMeasuredDimension(width, height);

}

  傳入的MeasureSpec是一個32位的整數,高兩位表示測量模式,低30位表示規格大小,這個整數指定了控制元件將如何進行具體的測量。最後利用更新後的width跟height設定測量結果的寬高。這個函式的主要作用是計算是否有margin/padding等造成額外的寬高,在必要時預留空間,並確定view的大小。

protected void onLayout(boolean changed, int left, int top, int right, int bottom) {

    super.onLayout(changed, left, top, right, bottom);

    if (mDeferScroll >= 0) {

        int curs = mDeferScroll;

        mDeferScroll = -1;

        bringPointIntoView(Math.min(curs, mText.length()));

    }

}

  在這裡呼叫了父類的onLayout函式

/**

 * Called from layout when this view should

 * assign a size and position to each of its children.

 *

 * Derived classes with children should override

 * this method and call layout on each of

 * their children.

 * @param changed This is a new size or position for this view

 * @param left Left position, relative to parent

 * @param top Top position, relative to parent

 * @param right Right position, relative to parent

 * @param bottom Bottom position, relative to parent

 */

protected void onLayout

(boolean changed, int left, int top, int right, int bottom) {

}

 可以看到View中該函式的註釋,可以知道這個函式的主要作用是對view的位置與大小進行賦值,以便下一步進行繪製。

@Override

protected void onDraw(Canvas canvas) {

    restartMarqueeIfNeeded();

    // Draw the background for this view

    super.onDraw(canvas);

    ......

    mTextPaint.setColor(color);

    mTextPaint.drawableState = getDrawableState();

    ......

    layout.draw(canvas, highlight, mHighlightPaint, cursorOffsetVertical);

    ......

}

 onDraw函式在該view需要進行渲染時呼叫,設定了具體的畫筆等引數,並呼叫draw進行具體繪製。

/**

 * Draw this Layout on the specified canvas, with the highlight path drawn

 * between the background and the text.

 *

 * @param canvas the canvas

 * @param highlight the path of the highlight or cursor; can be null

 * @param highlightPaint the paint for the highlight

 * @param cursorOffsetVertical the amount to temporarily translate the

 *        canvas while rendering the highlight

 */

public void draw(Canvas canvas, Path highlight, Paint highlightPaint,

        int cursorOffsetVertical) {

    final long lineRange = getLineRangeForDraw(canvas);

    int firstLine = TextUtils.unpackRangeStartFromLong(lineRange);

    int lastLine = TextUtils.unpackRangeEndFromLong(lineRange);

    if (lastLine < 0) return;

    drawBackground(canvas, highlight, highlightPaint, cursorOffsetVertical,

            firstLine, lastLine);

    drawText(canvas, firstLine, lastLine);

}

  在draw方法中分別呼叫對背景以及具體文字的繪製函式。 

  總而言之,我們可以重寫這些方法,來完成我們的控制元件自定義操作。

相關推薦

Android-UI控制元件繪製流程以及定義控制元件具體操作

  View檢視安卓應用中非常重要的組成部分,它不僅是構成應用介面的基本單元,還是與使用者互動的最直接物件。檢視View作為介面的基本元素,是由View System進行管理的。   在Android中,檢視控制元件主要被分成兩大類,一類是單一控制元件View,另外一類

Android平臺一款UI體驗好於NumberPicker的定義控制元件NumberPickerView

NumberPickerView another NumberPicker with more flexible attributes on Android platform 專案地址 前言 在平時開發中會用到NumberPicker元件,但

UI學習】Android github開源專案,酷炫定義控制元件(View)彙總

近期整理的比較酷炫並且我們會經常用到的custom view,也有一些不是custom view,但是也是android UI相關的,實現了酷炫UI效果的開源庫,總結的專案最後維護時間一般不會超過6個月,會持續更新,如果覺的不錯,歡迎star。如果描述有誤的話,歡迎大家

Android右滑關閉Activity介面功能-定義控制元件實現

引言Android右滑關閉Activity介面功能,網上已經有好多優秀的開原始碼和專案,不過大部分都是結合ViewDragHelper來實現的,這裡要討論的是通過結合ValueAnimator來實現,目前我的控制元件只實現了從左往右(上往下)滑關閉介面。需求在介面上從左往右滑

duilib中將xml封裝為控制元件簡單示例(簡單定義控制元件,封裝幾個基本控制元件合為1個定義控制元件)

使用duilib的時候,難免會有這樣的需求: 某一塊Container(Layout)以及裡面的佈局需要重複用,不想每次都複製貼上這麼多,要不然xml太大了; 通過繼承來自定義一個控制元件,比如CButtonUIEx之類的,想讓他像button一樣在xml中被識別; xml裡面的東西

WPF定義控制元件(四)の定義控制元件

原文: WPF自定義控制元件(四)の自定義控制元件 在實際工作中,WPF提供的控制元件並不能完全滿足不同的設計需求。這時,需要我們設計自定義控制元件。 這裡LZ總結一些自己的思路,特性如下: Coupling UITemplate Behaviour Function Package

Android之DatePicker和TimePicker實現以及定義大小

 關於日期和時間的幾個相關控制元件,包括DatePicker(日期選擇控制元件)、TimePicker(時間選擇控制元件)、DatePickerDialog(日期選擇對話方塊)、TimePickerDialog(時間選擇對話方塊)、AnalogClock(模擬時鐘控制元件

android中使用逐幀動畫實現定義progressbar元件

一 自定義progressbar   <1>素材:逐幀圖片若干張(根據自己loading元件的特點製作)   <2>定義每張圖片的顯示的順序及時間(定義幀動畫列表)       在res/drawable目錄下,  建立一根標籤為“animation

Android定義控制元件之《折線圖的繪製

金融軟體裡的行情分時圖,這是我們最常見的折線圖,當然了,折線圖的用途並不僅僅侷限於此,像一般在一定區間內,為了更好的能顯示出幅度的變化,那麼用折線圖來展示無疑是最符合效果的,當然了,網上也有很多的第

Android 定義控制元件 (一) ,柱狀圖 ,Canvas 繪製 柱狀圖 ,支援觸控操作

專案中,經常會用到統計圖表,個性化展示資料,增加趣味性,之前也用過百度Echarts來展示,效果很不錯,包括一些互動操作,不得不說,echarts幫我我們實現了絕大多數的需求,體積小不說,實現方式也很簡單,後來想了想,為什麼不用安卓Canvas繪製呢,畢竟是安卓開發攻城獅,下

Android 定義控制元件-Canvas和Paint繪圖詳解-手把手帶你繪製一個時鐘.

,Android - Paint基礎 在自定義控制元件時,經常需要使用canvas、paint等,在canvas類中,繪畫基本都是靠drawXXX()方法來完成的,在這些方法中,很多時候都需要用到paint型別的引數, Paint作為一個非常重要的元素,功能

Android定義控制元件之掃描動畫UI

前言 最近有一個需求,就是做一個掃描的UI,看了很多掃描動畫,發現酷狗的掃描動畫挺漂亮的,所以就做了一個相似的掃描動畫,廢話不多說,先看一下最終的效果吧。 最終效果圖 介紹 首先我們看一下這個效果,它由以下幾部分組成: 1.中間一個音符圖片

android-進階(3)-定義view(2)-Android中View繪製流程以及相關方法的分析

最近正在學自定義view,這篇文章主要講view的繪製流程和一些相關的方法,淺顯易懂,寫的非常好,忍不住就轉載了。             前言: 本文是我讀《Android核心剖析》第13章----View工作原理總結而成的,在此膜拜下作者 。

Android 定義控制元件之基礎幾何圖形繪製詳解

前言 距離寫上一篇自定義View文章已經大半年過去了,一直想繼續寫,但是無奈技術有限,生怕誤人子弟。這段時間專案剛剛完成,有點時間,跟著大神的腳步,鞏固下自定義View的相關基礎知識。 Canvas&Paint Canvas和Pa

Android UI高階之定義控制元件

在android中有許多控制元件,比如editview、button等,但是,有時這些控制元件並不能滿足我們的需求,這時,我們就需要去自定義一個控制元件來滿足我們的需要,下面給出一個仿360加速球的demo. 1、首先,來看一下360加速球的效果 2、

Android使用Java程式碼設定selector或drawable,以及使用定義控制元件方式使用它

鎮樓圖~~! TextView再給個selecotor 這種東西不要太簡單,但是這種東西我不想重複去寫N個Selector ! so~ /** * 獲取Selector * @param normalDraw *

Android中引入佈局和和定義控制元件

首先是引入佈局: 1.我們自己新建一個layout,就是一個標題欄。 2.然後在我們的mainactivity_layout中使用一個語句就可以實現。 <?xml version="1.0" encoding="utf-8"?> <LinearLayout

android-定義控制元件

自定義控制元件兩種方式 1、繼承ViewGroup 例如:ViewGroup , LinearLayout, FrameLayout, RelativeLayout等。 2、繼承View 例如:View, TextView, ImageView, Button等。 View的測量

定義控制元件學習之繪製刻度盤

以前面試的時候面試官問過我會不會寫標尺工具,我沒做過呀,然後胡亂的說什麼畫布,ondraw繪製。。然後就沒有然後了--!,現在想想真的有點囧。所以今天我試了下自己畫刻度盤,不是很難,只有方法對了,輕輕鬆鬆。。大神勿噴,這是菜鳥的日常(高手退散退散。。巴拉巴拉能量**>_<**)

Android 定義控制元件-星級評分

在學習自定義控制元件時需要一些例子來練練手,本文這個控制元件就是在這種環境下產生的(可能有BUG); 這個控制元件設計的特點: 1,可以任意修改星星數量 2,可以星星大小會隨控制元件大小而縮小,在控制元件足夠大的情況可以任意設定星星大小 3,滑動監聽,根據滑動距離選擇星級 4,可