1. 程式人生 > >Android面試準備:自定義控制元件

Android面試準備:自定義控制元件

Android自定義控制元件總結

  1. Android已經為我們提供了很多控制元件,但是大多數控制元件功能都比較單一簡單,不能滿足我們的需求,我們可以通過自定義控制元件的方式來實現自己想要的功能。
  2. Android實現自定義控制元件的方式一般有三種,第一種是繼承現有的控制元件,重寫相應的方法來擴充套件該控制元件的功能;第二種是繼承View類或者ViewGroup類,通過onDraw方法繪製控制,然後通過onMeasure方法設定控制元件的顯現,最後為自己繪製的控制元件設定監聽;第三種是通過組合控制元件來實現自定義控制元件,譬如說可以自定義一個控制元件,讓它既有ToggleButton的功能,又有ImageView的功能。
  3. 實現步驟為:
    1、在res/values/目錄下建立attrs.xml檔案,為自定義的控制元件設定屬性;
    3、在建構函式中將自定義控制元件與atrrs.xml中的屬性繫結起來
    4、在layout.xml檔案中為自定義控制元件的屬性設定值。
    5、setContentView顯示元件佈局

Android UI 引入

Android UI:不要覺得做UI不算什麼本事,Android app開發一定要過UI這一關,而不要只知道寫業務邏輯,只有想不到沒有做不到,喬布斯將UI與各種心理學綁上了關係,使用者互動設計師而不叫美工了,(有時間要好好學學,UI很重要,這樣才能實現一個完整的app)
課程目標

  1. 掌握View和ViewGroup
  2. 常用控制元件的使用
  3. View的本質
  4. Android 2D顯示圖形庫:Skia(openGF)——FrameBuffer
  5. 瞭解Android介面世界機制
  6. 熟練掌握自定義AndroidUI元件
  7. 熟練掌握Canvas(畫布)&Drawable畫自定義元件及事件處理
  8. NinePatch影象的熟練使用。

重點難點

  1. ListView控制元件的使用
  2. 瞭解Android介面事件的機制
  3. 熟練掌握自定義AndroidUI元件
  4. 熟練掌握Canvas(畫布)&Drawable畫自定義元件及事件處理熟練
  5. NinePatch影象的熟練使用
    (NinePatch:譬如說一個按鈕隨著所能容納的字數而拉伸)

考核目標
(面試中常見的問題)

  1. View類是所有控制元件的基類,能否說一下它與Activity的關係
  2. View的核心是什麼,能否說一下里面的onDraw函式
  3. 自定義元件如何實現自定義事件
  4. NinePatch是幹什麼的?會用麼?
  5. 簡單介紹一下Android介面事件機制

移動裝置介面設計的共性

  1. 怎麼做介面:介面別人設計好的app(抄襲 + 改良 = 創新)
  2. UI角色介紹
    1、使用者互動設計師:給想法和具體UI草圖
    2、視覺設計師(美工):實現想法、真正的介面效果圖
    3、介面實現:程式猿,或者編碼能力強的美工
    所以為什麼我們介面要用XML:將UI和程式碼分離
  3. 應用程式圖示要求
    1、一個應用程式的圖片不要超過2564、
    2、圖示的使用(畫素級的圖)怎麼讓自己的應用程式圖片比較醒目
  4. 資源的控制,能耗的控制(現在一般是以空間換時間,現在硬體的成本越來越廉價了,三星、硬體比較強、軟體比較弱)
    (對於能耗優化如果只是停止Service的執行緒外,不會怎麼省電,省電的方法有:關掉後臺、調節亮度、禁用其他不必要的功能。)
    能源消耗的主要部分:螢幕亮度 + CPU執行
  5. 不要滿足標準化的介面:只有想不到 沒有做不到

在Android UI就是由一個個View構成的,所有元件都是繼承View的,因此有必要通讀一下view類的原始碼

學習UI元件的方法:2 + 1原則

UI元件的實現(2 + 1 法則)

  1. 元件的呈現
    View的檢視呈現關係:
    1、呈現的兩種方式:
    什麼是動態佈局:一般的我們佈局是有一個Activity對應的xml佈局檔案,然後再Activity中使用方法setContentView(R.layout.XXX),這種方式成為靜態佈局,但是在動態佈局中,可以直接在Activity中建立一個ViewGroup,然後新增View,最後才呼叫setContentView(ViewGroup)動態顯示佈局
//建立一個容器類,佈局類,也就是ViewGroup
LinearLayout linearLayout = new LinearLayout(this);
//為LinearLayout設定屬性,略
//建立View物件,新增到ViewGroup中
Button btn = new Button(this);
linearLayout.addView(button);
//Viewgroup容器內的呈現
setContentView(linaerLayout(可以使ViewGroup,也可以是View))

2、呈現的核心
牢牢把握onDraw:Canvas + Drawable介紹
1、UI的呈現:佈局 + 位置
2、UI的事件:
瞭解了這兩個的話就知道怎麼實現自己的UI了

畫一個簡單的東西
可以在view或者SurfaceView(用在遊戲比較多,對圖片的切換要求更高),繼承View物件,實現onDraw(Canvas canvas)回撥方法,在回撥函式中:
步驟1:畫出一個佈局:繼承View,用Paint在Canvas畫畫

public class CustomView extends View{
    onDraw(Canvas canvas){
            //建立一個畫筆物件
            Paint paint = new  Paint();
            //為畫筆設定顏色
            paint.setColor(Color.Blue);
            //在畫布上呼叫畫筆畫畫
            canvas.drawRect(四個點座標,畫筆)
    }
}

步驟2:View的呈現
動態UI的載入,new一個UI物件,setContentView(UI物件)動態呈現佈局。

setContentView(new CostomView());

在主執行緒中重畫:要重畫的時候呼叫invalidate(),就會重新呼叫onDraw方法
在子執行緒中重畫:postInvalidate()
步驟3:為自定義的空間設定監聽。
譬如說點選事件:

customView.setOnClickListener(new OnClickListener(){
     onClick(){
    }
})

知識點補充:Android中UI的顯示需要底層類庫的支援,譬如說2D顯示的圖片:surface:(核心中:FrameBuffer驅動 + SurfaceFlinger)——Skia(2D影象的顯示引擎,也就是圖形顯示庫)——View、Canvas、Widget——Application
3D的顯示圖片:surface——OpenGL(3D影象顯示引擎)——Application

Android中事件

Android事件分類
1. keyEvent:與硬按鈕有關的事件,譬如說back按鈕、home按鈕、keyBoard按鈕
2. touchEvent:與螢幕互動的事件,點選、滑動、長按、多點觸控
3. 軌跡球(現在估計都沒有了,一直都在簡化按鈕)

事件觸發的兩種方法
4. 擴充套件View的時候實現回撥函式,即在控制元件內部(View)中實現,譬如說我們要實現自定義控制元件的時候。
5. 在Activity為空間註冊事件監聽器,內部已經有了該事件,在外部繼承來實現。

時間的分發

  1. KeyEvent分發:例如,點選收集上的一個按鍵的事件分發過程:點選訊息傳送到當前Activity—Activity再發給PhoneWindow—最後發給相應焦點的View
  2. touchEvent分發:與keyEvent反過來了

在自定義View中使用回撥事件
即在CustomView中新增方法:
public boolean onKeyUp(int keyCode, keyEvent event) {
if(keyCode == keyEvent.KEYCODE_DPAD_CENTER){
//點選後執行的操作
}
super();
}

public boolean onTouchEvent(MotionEvent evnet) {
if(event.getAction == MotionEvent.ACTION_UP) {

}
super();

}

遵循2 + 1 原則
2:佈局的呈現 (onMeasure:度量螢幕大小,用於擺放佈局;哦onDraw:用畫布畫出來)+ 佈局
1:事件(setXXLintener + 回撥函式)

自定義元件的分類:
1、Customized Component(自定義元件):當前元件不夠完善,想加入其它的功能,一般要繼承View,增加更多的屬性和時間。是一種深層次的擴充套件方式(縱向擴充套件)
2、Compound Component(複合空間):繼承ViewGroup,把多個簡單空間通過佈局拼裝一個複合控制元件,是一種橫向擴充套件。

自定義控制元件的步驟
1、選擇繼承類(肯定是View (View的子類)、Viewgroup)
2、類的初始化:初始化新增屬性 + 屬性的初始設定
3、過載方法:
a、佈局及呈現:onDraw + onMeasure
b、事件:自定義事件
4、元件的使用

Canvas & Drawable

用Canvas畫圖
(實際上Canvas用的不多)
1. Canvas的基本使用
1、drawXXX:建立畫筆物件,為畫筆設定屬性(SetXXX)、畫XXX圖形,使用View.invalidate()或者View.postInvalidate()方法實現重新呼叫drawXXX
2、matrix.setRotate(degree)旋轉 + matrix.setScale()放大/縮小; canvas.setMatrix(matrix)
3、clipRect(left、top、right、bottom)//裁剪一個區域
4、canvas.save + canvas.restore
2. 使用SurfaceView來畫圖:在遊戲中常用、雙快取、更快更平滑

Drawable類畫圖

  1. Drawable:抽象類,可以被畫出來的,包括BitMap(用的最多)、Nine Patch、Shape、Layers等
  2. 畫BitMap的時候必須呼叫setBound為圖片設定大小;
  3. 可以聯想到sources檔案下的Drawable檔案,即Drawable目錄下不止包括Bitmap,可畫的都可以放在裡面。
  4. Drawable(主要指的是Bitmap)的三種使用方式:
    1、用資原始檔中的圖片
    Android中支援的圖片格式:png(推薦)、jpg(可接受)、gif(不推薦)
public class DrawableView extends View {
    BitmapDrawable bd;

    public DrawaleView(Context context) {
        bd = (BitMapDrawable)getResources().getDrawable(R.id.XX);
        bd.setBounds(設定邊界);
    }

    public void onDraw(Canvas canvas) {
        //將Bitmap顯示在Canvas上
        super.onDraw(canvas);
        bd.draw(canvas);
    }

}

2、從XML檔案中的圖片
在res/Drawable/目錄下建立xml檔案
例如TransitionDrawable
3、也可以自定義Drawable物件
(實際開發中Drawable中比Canvas用得多得多)

Nine patch九宮圖

例如,button控制元件上,中間部分自適應控制元件中的文字。
nine - patch圖片的字尾為.9.png,Android中提供了相應制作Nine Patch圖片的工具(draw9Patch工具)。設定好可拉伸的位置。

3D-OpenGL

支援畫3D圖片給,做遊戲的時候會用到3D技術,不過現在OpenGL也很少用來畫3D圖片了,而是用引擎,譬如說Utinity

Spinner和ListViewer中的Adapter模式

ListView啊Spinner啊這些控制元件有相應的display方法將資料來源中的資料顯示在每一個Item上,但是資料來源中的資料型別呢可能有很多種,譬如說ArrayList陣列型別的資料來源啊,從資料庫中查詢得到的Coursor結果集,又或者是混合了多種控制元件的XML資料,如果ListView直接顯示這些資料來源資料的話可能要過載很多個display方法。這裡採用介面卡模式的話就是將這些不同型別的資料來源資料統一封裝成一個ArrayList型別的介面卡,再在ListView中顯示這個ArrayList資料來源資料就行了。