Android應用設計和Web應用設計相似,也分前端和後端設計。Android的核心要素和四大組件屬於後端設計部分,UI設計屬於前端設計。前端設計決定了用戶體驗的好壞,後端設計則決定了功能的完備和應用的安全、穩定。前端
對Android的UI設計來講,用到的最重要的兩個類是:View和ViewGroup。它們決定着展現給用戶的外觀界面的形狀。下面介紹下Android視圖系統的層次關係:java
View 類是全部視圖控件 (包括 ViewGroup) 的基類。 各類 UI 控件都繼承 View類,經過實現不一樣的接口實現特定功能。關於繼承關係,多說一下,方便你們更清楚的理解控件,見下圖:圖 2. 控件繼承關係
android
圖 3 . 經常使用的UI 控件
後端
Android 視圖框架 MVC 模型
Android 的 UI 框架也是採用的 MVC 進行組織的,它提供控制器處理用戶輸入,對模型作出相應操做,並將結果反饋到視圖,從新構建視圖、渲染到屏幕。
安全
Android 視圖執行過程分析app
在 Android 的開發中,視圖佈局,採用 XML 文件編寫,經過在 XML 文件中添加相應的控件,設置其屬性達到佈局的目的。一個簡單的佈局文件以下:框架
demo.xml 文件內容ide
<?xml version="1.0" encoding="utf-8"?> //聲明xml文件編碼及版本 <LinearLayout //使用線性佈局,對內部控件內部起做用,十七線性排列 //引用的命名空間 xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:padding="5dp" android:orientation="vertical" > //內部控件排列方向:垂直排列 <EditText //添加一個文本輸入框控件 android:id="@+id/show" //設置該控件ID //一下到結束爲該控件的各類屬性設置,使其在界面上顯示出特定樣式 android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:layout_weight="2" android:lines="3" android:editable="false" android:gravity="top|right" android:cursorVisible="true" android:text="" android:textSize="24sp" /> //結束該控件 </LinearLayout> //佈局結束標示
一個佈局文件(demo.xml)建立好後,新建一個 Test.java 文件來使用該佈局文件,以下:
Test.java文件內容模塊化
Fragment 表示 Activity 中的行爲或用戶界面部分。您能夠將多個片斷組合在一個 Activity 中來構建多窗格 UI,以及在多個 Activity 中重複使用某個片斷。您能夠將片斷視爲 Activity 的模塊化組成部分,它具備本身的生命週期,能接收本身的輸入事件,而且您能夠在 Activity 運行時添加或移除片斷(有點像您能夠在不一樣 Activity 中重複使用的「子 Activity」)。佈局
片斷必須始終嵌入在 Activity 中,其生命週期直接受宿主 Activity 生命週期的影響。 例如,當 Activity 暫停時,其中的全部片斷也會暫停;當 Activity 被銷燬時,全部片斷也會被銷燬。 不過,當 Activity 正在運行(處於已恢復生命週期狀態)時,您能夠獨立操縱每一個片斷,如添加或移除它們。 當您執行此類片斷事務時,您也能夠將其添加到由 Activity 管理的返回棧 — Activity 中的每一個返回棧條目都是一條已發生片斷事務的記錄。 返回棧讓用戶能夠經過按返回按鈕撤消片斷事務(後退)。
當您將片斷做爲 Activity 佈局的一部分添加時,它存在於 Activity 視圖層次結構的某個 ViewGroup 內部,而且片斷會定義其本身的視圖佈局。您能夠經過在 Activity 的佈局文件中聲明片斷,將其做爲
本文描述如何在開發您的應用時使用片斷,包括將片斷添加到 Activity 返回棧時如何保持其狀態、如何與 Activity 及 Activity 中的其餘片斷共享事件、如何爲 Activity 的操做欄發揮做用等等。
設計原理
Android 在 Android 3.0(API 級別 11)中引入了片斷,主要是爲了給大屏幕(如平板電腦)上更加動態和靈活的 UI 設計提供支持。因爲平板電腦的屏幕比手機屏幕大得多,所以可用於組合和交換 UI 組件的空間更大。利用片斷實現此類設計時,您無需管理對視圖層次結構的複雜更改。 經過將 Activity 佈局分紅片斷,您能夠在運行時修改 Activity 的外觀,並在由 Activity 管理的返回棧中保留這些更改。
例如,新聞應用可使用一個片斷在左側顯示文章列表,使用另外一個片斷在右側顯示文章 — 兩個片斷並排顯示在一個 Activity 中,每一個片斷都具備本身的一套生命週期回調方法,並各自處理本身的用戶輸入事件。 所以,用戶不須要使用一個 Activity 來選擇文章,而後使用另外一個 Activity 來閱讀文章,而是能夠在同一個 Activity 內選擇文章並進行閱讀,如圖 1 中的平板電腦佈局所示。
您應該將每一個片斷都設計爲可重複使用的模塊化 Activity 組件。也就是說,因爲每一個片斷都會經過各自的生命週期回調來定義其本身的佈局和行爲,您能夠將一個片斷加入多個 Activity,所以,您應該採用可複用式設計,避免直接從某個片斷直接操縱另外一個片斷。 這特別重要,由於模塊化片斷讓您能夠經過更改片斷的組合方式來適應不一樣的屏幕尺寸。 在設計可同時支持平板電腦和手機的應用時,您能夠在不一樣的佈局配置中重複使用您的片斷,以根據可用的屏幕空間優化用戶體驗。 例如,在手機上,若是不能在同一 Activity 內儲存多個片斷,可能必須利用單獨片斷來實現單窗格 UI。
建立片斷
想建立片斷,您必須建立 Fragment 的子類(或已有其子類)。Fragment 類的代碼與 Activity 很是類似。它包含與 Activity 相似的回調方法,如 onCreate()、onStart()、onPause() 和 onStop()。實際上,若是您要將現有 Android 應用轉換爲使用片斷,可能只需將代碼從 Activity 的回調方法移入片斷相應的回調方法中。
一般,您至少應實現如下生命週期方法:
onCreate()
系統會在建立片斷時調用此方法。您應該在實現內初始化您想在片斷暫停或中止後恢復時保留的必需片斷組件。
onCreateView()
系統會在片斷首次繪製其用戶界面時調用此方法。 要想爲您的片斷繪製 UI,您今後方法中返回的 View 必須是片斷佈局的根視圖。若是片斷未提供 UI,您能夠返回 null。
onPause()
系統將此方法做爲用戶離開片斷的第一個信號(但並不老是意味着此片斷會被銷燬)進行調用。 您一般應該在此方法內確認在當前用戶會話結束後仍然有效的任何更改(由於用戶可能不會返回)。
大多數應用都應該至少爲每一個片斷實現這三個方法,但您還應該使用幾種其餘回調方法來處理片斷生命週期的各個階段。 處理片斷生命週期部分對全部生命週期回調方法作了更詳盡的闡述。
您可能還想擴展幾個子類,而不是 Fragment 基類:
DialogFragment
顯示浮動對話框。使用此類建立對話框可有效地替代使用 Activity 類中的對話框幫助程序方法,由於您能夠將片斷對話框歸入由 Activity 管理的片斷返回棧,從而使用戶可以返回清除的片斷。
ListFragment
顯示由適配器(如 SimpleCursorAdapter)管理的一系列項目,相似於 ListActivity。它提供了幾種管理列表視圖的方法,如用於處理點擊事件的 onListItemClick() 回調。
PreferenceFragment
以列表形式顯示 Preference 對象的層次結構,相似於 PreferenceActivity。這在爲您的應用建立「設置」 Activity 時頗有用處。
添加用戶界面
片斷一般用做 Activity 用戶界面的一部分,將其本身的佈局融入 Activity。
要想爲片斷提供佈局,您必須實現 onCreateView() 回調方法,Android 系統會在片斷須要繪製其佈局時調用該方法。您對此方法的實現返回的 View 必須是片斷佈局的根視圖
圖 2. 片斷的生命週期(其 Activity 運行時)
1.layout_common.xml
複用的佈局文件
<?xml version="1.0" encoding="utf-8"?> <!-- 複用的佈局文件 --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" /> <Button android:id="@+id/common_button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="按鈕1" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" /> <Button android:id="@+id/common_button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="按鈕2" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" /> <Button android:id="@+id/common_button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="按鈕3" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" /> </LinearLayout>
2.layout_main.xml
主佈局文件 ,在這裏引用複用的佈局文件
<?xml version="1.0" encoding="utf-8"?> <!-- 主佈局文件 --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <RelativeLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_margin="16dp" android:layout_weight="1" > </RelativeLayout> <!-- 在佈局文件中引用複用的佈局文件 --> <include layout="@layout/layout_common" /> </LinearLayout>
3.CommonView.java
複用佈局文件實例化。單獨封裝,接口回調。 避免重複寫佈局文件,避免重複實例化控件,避免重複設置監聽方法
package com.example.mytestapp; import android.app.Activity; import android.content.Context; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; /** * 複用佈局文件實例化 */ public class CommonView implements OnClickListener { // 接口 public interface OnCommonViewClick { public void onButton1Click(View v); public void onButton2Click(View v); public void onButton3Click(View v); } public void setListener(OnCommonViewClick listener) { this.listener = listener; } Context mContext; OnCommonViewClick listener; public CommonView(Context context) { this.mContext = context; } public Button button1, button2, button3; public CommonView init() { button1 = (Button) ((Activity) mContext).findViewById(R.id.common_button1); button2 = (Button) ((Activity) mContext).findViewById(R.id.common_button2); button3 = (Button) ((Activity) mContext).findViewById(R.id.common_button3); button1.setOnClickListener(this); button2.setOnClickListener(this); button3.setOnClickListener(this); return this; } @Override public void onClick(View v) { if (listener == null) return; switch (v.getId()) { case R.id.common_button1: listener.onButton1Click(v); break; case R.id.common_button2: listener.onButton2Click(v); break; case R.id.common_button3: listener.onButton3Click(v); break; default: break; } } }
4.MainActivity.java
主界面實例化
package com.example.mytestapp; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.Toast; /* * 問題: * 1.如何用代碼改變控件的文字或顏色? */ public class MainActivity extends Activity implements CommonView.OnCommonViewClick { int clickTimes = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.layout_main); // 在這裏實例化佈局文件, 並實現監聽接口方法 // 只須要一行代碼就能夠直接完成複用代碼塊的實例化 new CommonView(this).init().setListener(this); } @Override public void onButton1Click(View v) { clickTimes++; // 在這裏實現對應點擊事件的方法 Toast.makeText(this, "你點擊了button" + clickTimes + "次", Toast.LENGTH_SHORT).show(); } @Override public void onButton2Click(View v) { // 在這裏實現對應點擊事件的方法 } @Override public void onButton3Click(View v) { // 在這裏實現對應點擊事件的方法 } }
. 屬性動畫出現的緣由
屬性動畫(Property Animation)是在 Android 3.0(API 11)後才提供的一種全新動畫模式
那麼爲何要提供屬性動畫(Property Animation)?
1.1 背景
實現動畫效果在Android開發中很是常見,所以Android系統一開始就提供了兩種實現動畫的方式:
逐幀動畫(Frame Animation)
補間動畫( Tweened animation )
1.2 問題
逐幀動畫 & 補間動畫存在必定的缺點:
a. 做用對象侷限:View
即補間動畫 只可以做用在視圖View上,即只能夠對一個Button、TextView、甚至是LinearLayout、或者其它繼承自View的組件進行動畫操做,但沒法對非View的對象進行動畫操做
有些狀況下的動畫效果只是視圖的某個屬性 & 對象而不是整個視圖;
如,現須要實現視圖的顏色動態變化,那麼就須要操做視圖的顏色屬性從而實現動畫效果,而不是針對整個視圖進行動畫操做
b. 沒有改變View的屬性,只是改變視覺效果
補間動畫只是改變了View的視覺效果,而不會真正去改變View的屬性。
如,將屏幕左上角的按鈕 經過補間動畫 移動到屏幕的右下角
點擊當前按鈕位置(屏幕右下角)是沒有效果的,由於實際上按鈕仍是停留在屏幕左上角,補間動畫只是將這個按鈕繪製到屏幕右下角,改變了視覺效果而已。
c. 動畫效果單一
補間動畫只能實現平移、旋轉、縮放 & 透明度這些簡單的動畫需求
一旦遇到相對複雜的動畫效果,即超出了上述4種動畫效果,那麼補間動畫則沒法實現。
即在功能 & 可擴展性有較大侷限性
1.3 問題
爲了解決補間動畫的缺陷,在 Android 3.0(API 11)開始,系統提供了一種全新的動畫模式:屬性動畫(Property Animation)
下面,我將全面介紹屬性動畫(Property Animation)
做用對象:任意 Java 對象
再也不侷限於 視圖View對象
實現的動畫效果:可自定義各類動畫效果
再也不侷限於4種基本變換:平移、旋轉、縮放 & 透明度
做用對象進行了擴展:不僅是View對象,甚至沒對象也能夠
動畫效果:不僅是4種基本變換,還有其餘動畫效果
做用領域:API11後引入的
在必定時間間隔內,經過不斷對值進行改變,並不斷將該值賦給對象的屬性,從而實現該對象在該屬性上的動畫效果
能夠是任意對象的任意屬性
具體的工做原理邏輯以下:
從上述工做原理能夠看出屬性動畫有兩個很是重要的類:ValueAnimator 類 & ObjectAnimator 類
其實屬性動畫的使用基本都是依靠這兩個類
因此,在下面介紹屬性動畫的具體使用時,我會着重介紹這兩個類。
ValueAnimator.ofInt(int values)
ValueAnimator.ofFloat(float values)
ValueAnimator.ofObject(int values)
下面我將逐一介紹。
5.1.1 ValueAnimator.ofInt(int values)
做用:將初始值 以整型數值的形式 過渡到結束值
即估值器是整型估值器 - IntEvaluator
5.1.32ValueAnimator.ofObject()
做用:將初始值 以對象的形式 過渡到結束值
即經過操做 對象 實現動畫效果
工做原理:
具體使用:
// 建立初始動畫時的對象 & 結束動畫時的對象 myObject object1 = new myObject(); myObject object2 = new myObject(); ValueAnimator anim = ValueAnimator.ofObject(new myObjectEvaluator(), object1, object2); // 建立動畫對象 & 設置參數 // 參數說明 // 參數1:自定義的估值器對象(TypeEvaluator 類型參數) - 下面會詳細介紹 // 參數2:初始動畫的對象 // 參數3:結束動畫的對象 anim.setDuration(5000); anim.start();