第二篇 界面開發 (Android學習筆記)

第二篇 界面開發 php

第5章 探索界面UI元素 html

The Android View Class java

 

 

●△Widget設計步驟 android

須要修改三個XML,以及一個class程序員

1)第一個xml是佈局XML文件(如:main.xml),是這個widget的。通常來講若是用這個部件顯示時間,那就只在這個佈局XML中聲明一個textviewOK了。 算法

2)第二個xmlwidget_provider.xml,主要是用於聲明一個appwidget的。其中,Layout就是指定上面那個main.xmlshell

3)第三個xmlAndroidManifest.xml,註冊broadcastReceiver信息。 數據庫

4)最後那個class用於作一些業務邏輯操做。讓其繼承類AppWidgetProviderAppWidgetProvider中有許多方法,通常狀況下咱們只是覆寫onUpdate(Context,AppWidgetManager,int[])方法。編程

 

●顏色表達 windows

RGB顏色查詢:http://www.atool.org/colorpicker.php

 

 

 

●幾個概念的關係

1.widget並非實際存在的類,它是一個包,而VIew等就是實際存在的類,因此首字母大寫。在引用時,一般:

import android.view.View;

import android.widget.TextView;

由於widget是包,因此首字母小寫

 

2.在該包內放的是UI Elements, 包括TextView,ListView,可是這些元素都繼承自ViewViewGroup。以下圖所示:

 

其中各類layout繼承自ViewGroup

 

Direct: extend directly from the super class.

Indirect: extend from a super class that directly extends the class in question.

※ 注意ViewGroup的派生類中有幾個類和View的幾個類重名.

 

 

View對象是Android平臺中用戶界面體現的基礎單位。

This class represents the basic building block for user interface components. A View occupies a rectangular area on the screen and is responsible for drawing and event handling. View is the base class for widgets, which are used to create interactive UI components (buttons, text fields, etc.). The ViewGroup subclass is the base class for layouts, which are invisible containers that hold other Views (or other ViewGroups) and define their layout properties.

 

View派生了TextView, EditText, ScrollView一部分UI組件類, widget(窗口小部件, widget不是類的名稱).

View還派生了ViewGroup, ViewGroup類下面AbsoluteLayout, GridLayout, LinearLayout等子類, 它們是容納、佈局各類widget的容器; ViewGroup類下面還有 另外一部分UI組件類, ListView這一UI組件:

java.lang.Object

    android.view.View

          android.view.ViewGroup

               android.widget.AdapterView<T extends android.widget.Adapter>

                    android.widget.AbsListView

                         android.widget.ListView

 

android.view和android.widget是兩個包;

android.view包 包括View類和ViewGroup(但不包括ViewGroup類的AbsoluteLayout等子類);

android.widget包 包括TextView, EditText, ScrollView, ListViewUI組件類, 以及ViewGroup類的AbsoluteLayout等子類.

 

android.view: Provides classes that expose basic user interface classes that handle screen layout and interaction with the user.

android.widget: The widget package contains (mostly visual) UI elements to use on your Application screen. You can also design your own.

 

●預知 Activity

一個Activity一般就是一個單獨的屏幕.

 

Android項目裏的proguard.cfg的做用

這是代碼混淆用的

代碼混淆是爲了防止你的apk被反編譯而代碼所有暴露.不過目前的代碼混淆只是把命名修改了一下而已,真正反編譯時仍是能夠想辦法還原出來的,因此不能真正的混淆.

 

AndroidMVC模式

MVC模式-- "模型-視圖-控制器"模式:

MVC是一種"架構模式"architectural pattern),不是設計模式(design pattern),屬於編程的方法論。

1)最上面的一層--"視圖層"View--負責給用戶提供操做界面,即程序的外殼。

2)最底下的一層--"模型層"Model--負責提供數據(data),或者業務邏輯(business logic)

3)中間的一層--"控制層"Controller--負責根據用戶從"視圖層"輸入的指令,選取"數據層"中的數據,而後對其進行相應的操做,產生最終結果,從而控制用戶界面數據顯示和更新Model層對象的狀態。    

 

A model stores data that is retrieved according to commands from the controller and displayed in the view; also, a model contains business logic.

Business Logic is comprised of Business Rules(業務規則) and Workflow(工做流程).

A view generates new output to the user based on changes in the model.

A controller can send commands to the model to update the model's state (e.g. editing a document). It can also send commands to its associated view to change the view's presentation of the model (e.g. by scrolling through a document).

 

A typical collaboration of the MVC components:

 

MVC的做用:

一、從開發者的角度來講:

MVC 模式不只實現了功能模塊和顯示模塊的分離,也就是說, 界面設計人員能夠直接參與界面開發,程序員就能夠把精力集中放在邏輯層和控制層上。

同時它還提升了應用系統的可維護性、可擴展性、可移植性和組件的可複用性

二、從用戶的角度來講:

用戶能夠根據本身的需求,選擇本身合適的瀏覽數據的方式。好比說,對於一篇在線文檔,用戶能夠選擇以HTML網頁的方式閱讀,也能夠選擇以pdf的方式閱讀。

 

Android中界面部分也採用了當前比較流行的MVC框架,在Android中:

1) 模型層(Model--數據和業務邏輯--程序員負責

對數據庫的操做、對網絡等的操做都應該在Model裏面處理,對業務計算等操做也是必須放在的該層的。

2) 視圖層(View--UI --界面設計人員負責

通常採用XML文件進行界面的描述。使用的時候能夠很是方便的引入。固然,如何你對Android瞭解的比較的多了話,就必定能夠想到在Android中也可使用JavaScript+HTML等的方式做爲View層,固然這裏須要進行JavaJavaScript之間的通訊,幸運的是,Android提供了它們之間很是方便的通訊實現。

3) 控制層(Controller--Activity--讓模型層和視圖層相分離--程序員負責

Android的控制層的重任一般落在了衆多的Acitvity的肩上,這句話也就暗含了不要在Acitivity中寫代碼,要經過Activity交割Model業務邏輯層處理,這樣作的另一個緣由是Android中的Acitivity的響應時間是5s,若是耗時的操做放在這裏,程序就很容易被回收掉。

 

AndroidM就是應用程序中二進制的數據,V就是用戶界面,CActivity, Activity負責控件的事件綁定以及業務流的程控制。Activity能夠有多個界面,只須要將視圖的ID傳遞到setContentView(),就指定了以哪一個視圖顯示模型層中的數據。

 

參考閱讀:

MVC (Model-View-Controller):M是指邏輯模型,V是指視圖模型,C則是控制器。

一個邏輯模型能夠對於多種視圖模型,好比一批統計數據你能夠分別用柱狀圖、餅圖來表示。

一種視圖模型也能夠對於多種邏輯模型。使用MVC的目的是將MV的實現代碼分離,從而使同一個程序可使用不一樣的表現形式。

C存在的目的則是確保MV的同步,一旦M改變,V應該同步更新,這與《設計模式》中的觀察者模式是徹底同樣。

 

Android SDK中的數據綁定,也都是採用了與MVC框架相似的方法來顯示數據。在控制層上將數據按照視圖模型的要求(也就是Android SDK中的Adapter)封裝就能夠直接在視圖模型上顯示了,從而實現了數據綁定。好比顯示Cursor中全部數據的ListActivity,其視圖層就是一個ListView,將數據封裝爲ListAdapter,並傳遞給ListView,數據就在ListView中現實。

 

Android UI開發的三種方法: XML; Java代碼; XMLJava代碼混合

XML: 比較方便、快捷,可是該方法有失靈活;

Java代碼: 雖然比較靈活,可是開發過程比較煩瑣;

XMLJava代碼混合: 習慣上把變化小、行爲比較固定的組件放在XML佈局文件中,把變化較多、行爲控制比較複雜的組件交給Java代碼來管理。

 

●詳細理解以下代碼

package com.wes.helloworld;

 

import android.app.Activity;

import android.os.Bundle;

 

public class mainActivity extends Activity {

    //重寫繼承與父類Activity的函數onCreate()

    @Override

    public void onCreate(Bundle savedInstanceState) {

    // Android系統用一個Activity來初始化一個程序

    //這個Activity始於一個onCreate()回調方法

    //Bundle型的savedInstanceState保存了當前Activity的狀態信息

    //Bundle類是一個key-value對,相似於Map

 

        super.onCreate(savedInstanceState);

        //調用父類的onCreate()函數

        //之因此要寫super,是由於上面有個被重寫的父類的onCreate()方法

        //這一條語句用來初始化Activity,即生成一個空白的Activity

        setContentView(R.layout.main);

        //這句話的意思是 設置 這一條語句所在的Activity 採用 R.layout下的main佈局文件進行佈局

        //對於R.layout.mainlayoutR.java裏面的public static final class layout

        //mainlayout類裏面的public static final int 類數據成員

    }

}

各類圖片, raw資源→佈局→代碼

一個Activity的基本代碼佈局

    派生一個Activity{

        聲明已經在.xml文件中定義的控件;

        聲明本Activity自帶的數據(能夠從項目的res目錄中得到);

        聲明用於更新UI界面的Handler;

        protected void onCreate(Bundle savedInstanceState){

            super.onCreate(savedInsatanceState);

            setContentView(R.layout.*);

 

            狀況1://若是要下面的代碼要操做相關數據, 將獲取數據的代碼寫在這兒

            //不一樣於第②步中聲明的本Activity自帶的數據, 這裏的數據通常是從其它Activity得到, 或者                是用戶本身在本Activity內輸入的

            //例如, 要獲取其它Activity傳來的數據, 可在此獲取Inten類對象, 例如:

            Intent intent=getIntent();

            狀況2://若是要使用bindService()方法啓動Service, 須要在此聲明一個ServiceConnection對象

            並將ServiceConnection()這一構造方法裏的onServiceDisconnected()onServiceConnected()這兩            個回調方法完成

 

            狀況1:獲取佈局中設置的控件(要先在layout裏爲相關控件賦予R文件裏的id, 不然文件源文件                一直出錯), 並賦值給第②步中獲取的控件;    

            狀況2:獲取ContentResolver對象

            .(接着, 在獲取Uri, 註冊ContentObserver,

            並在onCreate()方法以外的區域實現自定義的ContentResolver)

 

            //若是這裏獲取了一個ListView控件, mListView, 接着建立一個自定義的Adapter類的實例,

             //mAdapter, 而後設置Adapter, 例如mListView.setAdapter(mAdapter);

            //自定義的Adapter類的實如今第⑤步

            //注意, 咱們也多是在某個onCreate()的一個新定義的方法內操做這一步

 

            //若是這裏有個initView()方式, 那麼事件監聽的相關代碼、以及對獲取並賦值控件的代碼在

            onCreate()方法以外的區域裏的

            //initView()方法裏實現

 

            //最後通常是使用BroadbandcastReceiver4個步驟中的前三步:

            1. 新建一個Intent過濾器

            2. 新建一個BroadcastReceiver

            3. 註冊廣播接收器

 

            編寫與控件相關的監聽器內的各類回調函數(onClick())代碼;

            //startService(), stopService(), bindService(), unbindService()等服務組件的回調方法在onClick

            //回調函數內實現

        }

        

        //下面都是onCreate()方法以外的區域

        //若是onCreate()onClick()等回調函數的函數體內若是調用了自定義的方法, 可在此具體實現;

        //其它任何具體具體的函數都在此定義

        //使用BroadbandcastReceiver的最後一步: 4. 註銷廣播接收器

}

//另外注意:

1. ContentResolver可能出如今子線程的某個自定的方法裏, 也可能出如今主線程的onClick()等回調方法裏;

2. 每啓動一個應用進程,都會建立與之對應的ActivityThread類的實例,它是應用程序的UI線程,Android進程啓動時會創建消息循環;

3. 子線程通常在onCreate()方法內, 或者是onCreate()裏面嵌套的其它方法內建立

4. 通常來講, Activity類不用具體實現構造方法

一個ContentProvider的基本代碼佈局:

1. 新建一個類,繼承自ContentProvider

2. 重寫onCreate(), delete(), getType(), insert(), query(), update()等方法, 可增長自定義的方法

  • 在開發中一般使用常量來定義URI,以下面的CONTENT_URI

public static final String AUTHORITY = "com.alexzhou.provider.NoteProvider";

public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/notes");

一個BroadcastReceiver基本代碼佈局:

1. 新建一個類,繼承自BroadcastReceiver類

2. 重寫onReceive()方法; 可增長自定義的方法

一個Service基本代碼佈局:

1. 新建一個類,繼承自Service

2. 重寫Service的幾個重要方法;可增長自定義的方法

 

 

●回調函數()

A callback function is a function which is:

passed as an argument to another function, and,

is invoked after some kind of event.

 

 

當程序跑起來時,通常狀況下,應用程序(application program)時常會 經過API 調用庫裏所預先備好的函數。可是有些庫函數(library function)卻要求應用先傳給它一個函數,好在合適的時候調用,以完成目標任務。這個被傳入的、後又被調用的函數就稱爲回調函數(callback function)。

對於C/C++而言,函數名就是函數的地址,就是函數的指針,不須要在進行取地址操做函數名就是函數的地址,就是函數的指針,不須要在進行取地址操做.

回調函數就是一個經過函數指針調用的函數。

若是你把一個函數指針(地址)做爲參數傳遞給另外一個函數,當這個指針被用來調用其所指向的函數時,咱們就說這個被指向的函數是回調函數。回調函數不是由該函數的實現方直接調用,而是在特定的事件或條件發生時由另外的一方調用的,用於對該事件或條件進行響應。

例如:

你到一個商店買東西,恰好你要的東西沒有貨,因而你在店員那裏留下了你的電話,過了幾天店裏有貨了,店員就打了你的電話,而後你接到電話後就到店裏去取了貨。

上面整個案例是一個主程序(Main program

"通知到貨"這個商店提供的服務是庫函數(Library function

你的電話號碼是回調函數(Callback function這個回調函數的函數體就是讓"你"去商店取貨

你把電話留給店員就叫登記回調函數(咱們還能夠登記其它回調函數, 例如微信號,QQ號等)

店裏後來有貨了叫作觸發了回調關聯的事件

店員(店員是回調函數的調用者 Caller)給你打電話叫作調用回調函數(不必定要通話)

("你"是事件監聽器 Event Listener)到店裏去取貨叫作響應回調事件

至於我怎麼去取貨,即我怎麼完成電話號碼這個回調函數,我能夠騎自行車去取,坐出租車去取,或者叫別人去取,這叫重寫回調函數

 

店員是調用者他不用在乎被調用者(即回調函數)究竟是什麼, 能夠是電話號碼, 能夠是微信號, QQ號等。若是使用電話號碼這個回調函數, 咱們就不用總是去問到沒到貨, 等電話就好了。

能夠看到,回調函數一般和應用處於同一抽象層(由於傳入什麼樣的回調函數是在應用級別決定的)。而回調就成了一個高層調用底層,底層再回過頭來調用高層的過程。(我認爲)這應該是回調最先的應用之處,也是其得名如此的緣由。

回調函數不是由程序員主動在程序中指定函數名來調用, 而是由系統根據某些特定條件的觸發(例如點擊). Android系統決定調用對應的回調函數, 實行對應的功能.

typedef void (*CALLBACK)(int a,int b)

定義一個函數指針CALLBACK,它返回void類型,有兩個參數,分別爲,a,b.

callback的幾種解釋:

A "callback" is any function that is called by another function which takes the first function as a parameter. A lot of the time, a "callback" is a function that is called when something happens. That something can be called an "event" in programmer-speak(程序員說的"事件").

 

A callback is a piece of executable code that is passed as an argument to other code, which is expected to call back (execute) the argument at some convenient time. The invocation may be immediate as in a synchronous callback, or it might happen at a later time as in an asynchronous callback.

//請看下面的僞代碼

// The callback method

function meaningOfLife() 

{

log("The meaning of life is: 42");

}

 

 

// A method which accepts a callback method as an argument

// takes a function reference to be executed when printANumber completes

function printANumber(int number, function callbackFunction)

{

print("The number you provided is: " + number);

}

 

// Driver method

function event() //例如在Android, 因爲觸摸(Touch)而觸發的事件會使回調函數被調用

{

printANumber(6, meaningOfLife);    

    //C語言中, A函數作B函數的參數的方法是定義A函數的函數指針

}

 

●爲何要用回調函數?

由於能夠把調用者與被調用者分開。調用者不關心誰是被調用者,全部它需知道的,只是存在一個具備某種特定原型、某些限制條件(如返回值爲int)的被調用函數。

若是想知道回調函數在實際中有什麼做用,先假設有這樣一種狀況,咱們要編寫一個庫,它提供了某些排序算法的實現,如冒泡排序、快速排序、shell排序、shake排序等等,但爲使庫更加通用,不想在函數中嵌入排序邏輯,而讓使用者來實現相應的邏輯;或者,想讓庫可用於多種數據類型(intfloatstring),此時,該怎麼辦呢?可使用函數指針,並進行回調。

回調可用於通知機制,例如,有時要在程序中設置一個計時器,每到必定時間,程序會獲得相應的通知,但通知機制的實現者對咱們的程序一無所知。而此時,就需有一個特定原型的函數指針,用這個指針來進行回調,來通知咱們的程序事件已經發生。實際上,SetTimer()API使用了一個回調函數來通知計時器,並且,萬一沒有提供回調函數,它還會把一個消息發往程序的消息隊列。

另外一個使用回調機制的API函數是EnumWindow(),它枚舉屏幕上全部的頂層窗口,爲每一個窗口調用一個程序提供的函數,並傳遞窗口的處理程序。若是被調用者返回一個值,就繼續進行迭代,不然,退出。EnumWindow()並不關心被調用者在何處,也不關心被調用者用它傳遞的處理程序作了什麼,它只關心返回值,由於基於返回值,它將繼續執行或退出。

 

  • 更接近問題本質的答案:

根據面向對象設計的封裝性要求,模塊間要解耦,模塊內要內聚.

 

  • Android, 回調函數實際上就起到了消息循環的做用,由於在SDK中只有經過回調函數來發送各自的處理消息.

 

Callback最本質的特徵包括兩點:註冊和觸發

Callback函數是你提供給系統調用的函數。不少狀況下,系統某個狀況下,定義須要執行某個操做,而操做自己由有用戶的程序來提供,這時,就要用到回調函數了。因此,簡單地說。回調函數,就是你寫一個函數,在系統定義的地點提供給系統調用。

 

C語言回調函數案例

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

/* callback.c */

#include<stdio.h>

#include"reg_callback.h"

   

/* callback function definition goes here */

void my_callback(void)

{

printf("inside my_callback\n");

}

   

int main(void)

{

/* initialize function pointer to

my_callback */

callback ptr_my_callback=my_callback;

printf("This is a program demonstrating function callback\n");

/* register our callback function */

register_callback(ptr_my_callback);

printf("back inside main program\n");

return 0;

}

1

2

3

/* reg_callback.h */

typedef void (*callback)(void);

void register_callback(callback ptr_reg_callback);

1

2

3

4

5

6

7

8

9

10

11

/* reg_callback.c */

#include<stdio.h>

#include"reg_callback.h"

   

/* registration goes here */

void register_callback(callback ptr_reg_callback)

{

printf("inside register_callback\n");

/* calling our callback function my_callback */

(*ptr_reg_callback)();

}

This is a program demonstrating function callback

inside register_callback

inside my_callback

back inside main program

 

JAVA中不容許直接操做指針,那它的回調是如何實現的呢?

答案:它是經過接口或者內部類來實現的。

 

JAVA方法回調是功能定義和功能實現分享的一種手段,是一種耦合設計思想。做爲一種架構,必須有本身的運行環境,而且提供用戶的實現接口。

1. 定義接口 Callback ,包含回調方法 callback()
2.
在一個類Caller 中聲明一個Callback類型的引用變量(不是接口對象) mCallback
3.
在程序中賦予 Caller對象的接口成員(mCallback) 一個內部類對象如
interface Callback(){
    callback
(){
    //
函數的具體實現
    }
}

 

Class Caller{

    Callback mCallback;

}

 

這樣,在須要的時候,可用Caller對象的mCallback接口成員 調用callback()方法,完成回調。

接口是不能實例化,可是,接口能夠聲明引用變量。

接口的引用能夠指向凡是實現了該接口的類的實例(多態)。

下面的語句並不是直接實例化接口, 由於new Runnable(){}中的花括號裏面具體實現了接口的方法:

Runnable task = new Runnable() {

    public void run() {

    

    }

};

 

●監聽器

A、什麼是監聽器?

您須要記住如下幾點:

1監聽器其實是一個接口,它包含了一個事件觸發時系統會去調用的回調函數

二、在實現接口的類中,根據您項目的須要重寫這個回調函數

3、派生後的監聽器須要綁定到按鈕上,就像一個耳機能夠發出聲音,但您不去戴它,您是聽不到它發出的聲音的。通常的狀況是這個按鈕可能須要這個監聽器,而另一個按鈕須要另一個監聽器,每一個監聽器各司其職,但功能類似時,也能夠多個按鈕共同綁定一個監聽器。

4、各類控件,都有經常使用的事件,如點擊按鈕,拖動一個滾動條,切換一個ListView的選項等等,它的綁定監聽器的函數命名規則是setOn****Listener

 

B、爲控件綁定監聽器主要分爲如下步驟:

① 獲取表明控件的對象

② 定義一個類,實現監聽器接口

③ 生成監聽器對象

④ 爲控件綁定監聽器對象

 

Android程序中,設置View點擊事件監聽共有四種

1)在佈局文件中爲控件設置onClick屬性指定點擊方法;

2)建立一個內部類實現OnClickListener接口並重寫onClick()方法,

以後須要爲控件設置setOnClickListener(Listener listener)

3)主類中實現OnclickListener接口,而後重寫onClick()方法;

4)建立匿名內部類,即在爲控件設置監聽時直接建立一個

OnClickListener實例,不爲該實例指定名稱。

 

以"用戶觸碰(touch)"這一動做來說,當組件要處理用戶觸碰的事件時,組件做爲事件源要註冊一個事件監聽器對象,即:

void setOnClickListener(View.OnClickListener l) //註冊單擊事件

再如:

void setOnLongClickListener(View.OnLongClickListener l)    //註冊長按事件

void setOnKeyListener(View.OnKeyListener l)    //註冊鍵盤事件

void setOnFocusChangeListener(View.OnFocusChangeListener l)    //註冊焦點改變事件

void setOnTouchListener(View.OnTouchListener l)        //註冊觸摸事件

void setOnCreateContextMenuListener(View.OnCreateContextMenuListener l)    //註冊上下文菜單事件當這樣當"touch"事件發生時,Android框架便回調事件監聽器裏的回調函數。

 

View.OnClickListener是click listener,即UI控件的Click動做監聽器;當用戶對View進行Click操做時(即觸控上的UI組件),Android框架便會回調這個View.OnClickListener的回調函數,即onClick()

  • 另一種UI事件的機制爲事件處理器(event handler),event handler與event listener是不同的處理機制,下文會講到。

 

●View與ViewGroup觸摸事件傳遞機制

觸摸事件有:ACTION_DOWN, ACTION_MOVE, ACTION_UP 。一個簡單的觸摸動做觸發了一系列Touch事件,如:

 

1ACTION_DOWN -> ACTION_MOVE->..-> ACTION_MOVE-> ACTION_UP

 

2ACTION_DOWN -> ACTION_UP

 

TouchEvent發生時,首先ActivityTouchEvent傳遞給最頂層的ViewTouchEvent最早到達最頂層ViewdispatchTouchEvent,而後由dispatchTouchEvent方法進行分發,若是dispatchTouchEvent返回TRUE,則交給這個ViewonTouchEvent處理;若是dispatchTouchEvent返回false,則交給這個ViewOninterceptTouchEvent方法來決定是否要攔截這個事件,若是OninterceptTouchEvent返回true,也就攔截了,則交給它的onTouchEvent來處理;若是OninterceptTouchEvent返回false,那就傳遞給子View,由子ViewdispatchTouchEvent再來開始這個事件的分發,若是事件傳遞到某一層ViewonTouchEvent了,這個方法返回false,那麼這個事件從這個View往上傳遞,都是onTouchEvent來接收,而若是傳遞到onTouchEvent返回是false,這個事件"消失",並且接收不到下一次事件。

 

其分發和傳遞的過程以下:

 

 

 

●There are following three concepts related to Android Event Management

(Android事件管理的3種機制)

  • Event Listeners (事件監聽器)− An event listener is an interface in the View class that contains a single callback method. These methods will be called by the Android framework when the View to which the listener has been registered is triggered by user interaction with the item in the UI.
  • Event Listeners Registration (事件監聽器註冊)− Event Registration is the process by which an Event Handler gets registered with an Event Listener so that the handler is called when the Event Listener fires the event.
  • Event Handlers (事件處理器)− When an event happens and we have registered an event listener for the event, the event listener calls the Event Handlers, which is the method that actually handles the event.

 

(不用掌握, 掌握書上的方法便可)爲控件綁定監聽器主要分爲如下步驟:

1、獲取表明控件的對象

2、生成監聽器對象

3、爲控件綁定監聽器對象

4、定義一個類,實現監聽器接口

protected void onCreate(Bundle savedInstanceState) { 

 super.onCreate(savedInstanceState); 

 setContentView(R.layout.activity_main); 

 textView =(TextView)findViewById(R.id.textView); 

 textView.setText("set text success"); 

 //1.獲取表明控件的對象 

 button =(Button)findViewById(R.id.button); 

 //2.生成監聽器對象 

 ButtonListener buttonListener =new ButtonListener(); 

 //3.爲控件綁定監聽器對象 

 button.setOnClickListener(buttonListener); 

 } 

 

 //4.定義監聽類,實現監聽器接口 

 class ButtonListener implements OnClickListener{ 

 

 @Override 

 public void onClick(View arg0) { 

 // TODO Auto-generated method stub 

 textView.setText("onclick ok"); 

 } 

 

}

 

●接口與內部匿名類

接口不能實例化,可是接口類型的引用變量能夠引用一個實現了接口的類的對象.

 

接口 對象=new 接口的實現類()

 

//這裏可使用匿名內部類實現接口

(new 接口(){

//實現方法

});

//其中, FilenameFilter是一個接口, 上面實現的是FilenameFilter接口的匿名內部類, 並非FileNameFilter的實例化.

 

該代碼等效於

class A implements FileNameFilter{    //這裏給上面的匿名內部類起了個名字A

    public void accept(File f,String s)

    {

        //實現了accept()這個回調函數

    }

}

 

dir.list(new A())

 

●問題

設有下面兩個賦值語句:

a = Integer.parseInt("123");

b = Integer.valueOf("123").intValue();

下述說法正確的是( d )。

A、a是整數類型變量,b是整數類對象。

B、a是整數類對象,b是整數類型變量。

C、ab都是整數類對象而且值相等。

D、ab都是整數類型變量而且值相等。

注意, 若是b = Integer.valueOf("123").intValue();中沒有intValue(), 那麼a是基本數據類型int, bInteger包裝類類型.

 

Integer.valueOf() 和 String.valueOf()

既有Integer.valueOf()函數, 也有String.valueOf()函數

 

●爲何定義在類頭上的控件變量須要是final

由於在安卓中 不少監聽器之內部類的形式去訪問定義在類頭上的控件(如一個Button)變量,這就造成了內部類與外部類變量的訪問;注意,這裏的控件變量須要加final關鍵字 。

由於若是不加final,那個變量的生命將在方法結束時結束,但那個匿名內部類的對象仍然存在,它就須要訪問一個已經不存在了的變量。加了final後生命週期延長,就不會有這個問題了。

 

GridViewListView

 

MainActivity.this 和直接用 this有區別嗎?

MainActivity.this表示的就是MainActivity這個類對象自己,這種寫法通常用在內部類裏,由於在外部類中直接能夠用關鍵字this表示本類,而內部類中直接寫this的話表示的是內部類自己,想表示外部類的話就得加上外部類的類名.this

※ 對於包含內部類的類來講,它就是其內部類的外部類。

 

具體來講, 某個控件 setOnClickListener(); 在括號裏面new 一個OnClickListener (這就建立了上面說的內部類),而後在onClick方法裏面處理的時候必需要用MainActivity.this 而不能用this

 

※ 下面有關風格和主題的講述比較雜亂

Android應用開發中的風格和主題(style,themes)

風格和主題都是資源, 存放在res/values 文件夾下,你能夠用android提供的一些默認的風格和主題資源,你也能夠自定義你本身的主題和風格資源。

如何新建自定義的風格和主題:

1. 在res/values 目錄下新建一個名叫style.xml的文件。增長一個<resources>根節點。

2. 對每個風格和主題,給<style>element增長一個全局惟一的名字,也能夠選擇增長一個父類屬性。在後邊咱們能夠用這個名字來應用風格,而父類屬性標識了當前風格是繼承於哪一個風格。

3. 在<style>元素內部,申明一個或者多個<item>,每個<item>定義了一個名字屬性,而且在元素內部定義了這個風格的值。

4. 你能夠應用在其餘XML定義的資源。

 

Android提供的默認的主題樣式

Android的Style設計就是提高用戶體驗的關鍵之一。Android上的Style分爲了兩個方面:

1,Theme(主題)是針對窗體級別的(Activity),用來改變窗體樣式;

2,Style(風格)是針對窗體元素級別的,改變指定控件或者Layout的樣式。

 

Android系統的themes.xmlstyle.xml(位於系統源代碼frameworks\base\core\res\res\values\)包含了不少系統定義好的style,建議在裏面挑個合適的,而後再繼承修改。

好比說android:theme="@android:style/Theme.Dialog"可讓你的Activity變成一個窗口風格,

android:theme="@android:style/Theme.Light"則讓你的整個Activity具備白色的背景,而不是黑色那麼沉悶。

詳見:http://www.cnblogs.com/SharkBin/p/3596525.html

 

具體使用方法很簡單, Androidmanifest.xml文件中對你的Activity節點上加入些代碼,以下圖所示:

 

●△引用主題屬性:

另一種資源值容許你引用當前主題中的屬性的值。這個屬性值只能在樣式資源和XML屬性中使用;它容許你經過將它們改變爲當前主題提供的標準變化來改變UI元素的外觀,而不是提供具體的值。

 

android:textColor="?android:textDisabledColor"

 

當你使用這個標記時,你就提供了屬性資源的名稱,它將會在主題中被查找--由於資源工具知道須要的屬性資源,因此你不須要顯示聲明這個類型(若是聲明,其形式就是?android:attr/android:textDisabledColor)。除了使用這個資源的標識符來查詢主題中的值代替原始的資源,其命名語法和"@"形式一致:?[namespace:]type/name,這裏類型可選。

 

The question mark means it's a reference to a resource value in the currently applied theme.(問號的意思是它是當前被應用的主題中的資源值的引用)

 

●適配器 Adapter

Android適配器是數據和視圖之間的橋樑,能夠看做是將界面和數據綁定的工具,以便於數據在視圖上顯示。咱們經常使用的適配器一共有三個:ArrayAdapterSimpleAdapterSimpleCursorAdapter 這三個,他們都是繼承於BaseAdapter

 

 

※ 現實中的適配器有不少, 如顯卡(Video cardGraphics card/顯示適配器。

 

ArrayAdapter的第二個參數還有以下幾個參數能夠設置

  • 1)android.R.layout.simple_list_item_1:由文字組成的列表項。
  • 2)android.R.layout.simple_list_item_2:由稍大的文字組成的列表項。
  • 3)android.R.layout.simple_list_item_checked:由CheckBox組成的列表項。
  • 4)android.R.layout.simple_list_item_multiple_choice:有多選框組成的列表項
  • 5)android.R.layout.simple_list_item_single_choice:有單選框組成的列表項。

 

●Android系統中提供了兩種圖片瀏覽方式

圖片瀏覽器是智能設備中使用很是普遍的組件,Android系統中提供了兩種圖片瀏覽方式,

① 最爲普通的ImageView瀏覽,

② 使用GridView實現網格式的圖片瀏覽,

 

 

 

 

 

 

 

第6章 使用程序資源

●資源(

Resources

本質上, 資源是一種共享、反覆利用元素、屬性的機制(mechanism)

 

●資源的圖示

 

資源類型

文件夾名稱

文件名

字符串

/res/values/

strings.xml

字符串數組

/res/values/

arrays.xml

顏色

/res/values/

colors.xml

樣式

/res/values/

styles.xml

主題

/res/values/

themes.xml

圖片

/res/drawable/

*.png*.jpg*.gif

佈局

/res/layout/

mylayout.xml

動畫

/res/anim/

*_anim.xml

菜單

/res/menu/

menu1.xml

原始文件

/res/raw/

audio.mp3video.mp4

XML文件

/res/xml/

自定義的xml文件

 

 

"@+id/""@type/name""@+android:id/title "

1、引用自定義資源

1.引用自定義資源。格式:@[package:]class/name

例如:

android:text="@string/hello"

android:layout_toRightOf="@id/btnLogin"

注:idR.java裏也是一種class

 

@表示對資源的引用,package是包名,若是在相同的包內,則包名能夠省略。

"@string/hello"的意思是引用在strings.xml裏面定義的字符串,屬性(引用變量)爲hello,值(引用變量指向的對象)爲Hello World

 

2.引用系統資源。格式:@android:type/name

android:textColor="@android:color/opaque_red"

 

2、 新建一個資源id

<EditText

android:id="@+id/edit"

.../>

edit這個id表明EditText這個UI控件,系統會在R.java文件中自動生成int edit = 十六進制的value

咱們能夠在Java代碼中使用edit這個id,例如:

EditText et=(EditText)findViewById(R.id.edit);

//id是R.java文件裏的,即public static final class idedit是這個類的成員。

加上android:表示引用android.R.id裏面定義的id資源,若是android.R.id裏面確實有title這個id資源,就直接使用它,若是沒有的話就在當前應用的R.id中產生一個title標識.

 

※ 可是如今我發現apps/settings/res/layout/preferenc_progress.xml中有個"@+android:id/title",怎麼理解它?

"@+android:id/title"表示在系統的R.java文件中自定義一個名爲titleid

 

再如:

系統佈局文件是:android.R.layout.xxx;

而用戶自定義佈局文件是:R.layout.xxx;

 

id是控件的一個基本屬性,這並不表明每一個控件的id都不同,其實控件的id屬性是能夠相同的

全部的控件被加載到內存之後就會造成一個控件樹形結構,當查找控件的時候,只返回第一個id匹配的控件,因此若是一個頁面中有相同id的控件,好比ListViewitem,當查找控件的時候要從它最鄰近的一個父節點開始查找,這樣纔會命中.

 

res/rawassets

res/raw和assets的相同點:

二者目錄下的文件在打包後會原封不動的保存在apk包中,不會被編譯成二進制。


res/raw和assets的不一樣點:
1.
 res/raw中的文件會被映射到R.java文件中,訪問的時候直接使用資源ID

即R.類名.數據成員名

//類名如:attr, color, drawable, id, layout, raw, string

//(有的類名採用的是文件夾名,如res/layout/, 有的類名採用的是.xml文件裏面的標籤名,如res/values/.strings.xml文件裏的string標籤名)

assets文件夾下的文件不會被映射到R.java中,訪問的時候須要AssetManager類。
2.res/raw
不能夠有目錄結構,而assets則能夠有目錄結構,也就是assets目錄下能夠再創建文件夾

 

3.讀取文件資源的方式

①讀取res/raw下的文件資源,經過如下方式獲取輸入流來進行寫操做

  1. InputStream is = getResources().openRawResource(R.類名.數據成員名);

②讀取assets下的文件資源,經過如下方式獲取輸入流來進行寫操做

  1. AssetManager am = null;
  2. am = getAssets();
  3. InputStream is = am.open("filename");

 

補充一下:在未知目錄下有一些文件,那麼該怎麼獲取這些文件的名稱並把文件拷貝到目標目錄中呢?(用於內置文件但不知道文件名稱,須要篩選出想要的文件而後拷貝到目標目錄中,推薦內置在assets文件夾中)
1.res/raw
目錄:
經過反射的方式獲得R.java
裏面raw內部類裏面全部的資源ID的名稱,而後經過名稱獲取資源ID的值來讀取咱們想要的文件。(這個方法我沒試過,有用過的同窗麻煩發一段代碼看看)。
2.assets
目錄:
getAssets().list("");
來獲取assets目錄下全部文件夾和文件的名稱,再經過這些名稱再讀取咱們想要的文件。

 

raw目錄先放置一個MP3文件

 

R.java文件與res文件的對應關係:

除了string.xml, res/value/文件下可能包含的xml文件:

arrays.xml for resource arrays, and accessed from the R.array class.

integers.xml for resource integers, and accessed from the R.integer class.

bools.xml for resource boolean, and accessed from the R.bool class.

colors.xml for color values, and accessed from the R.color class.

dimens.xml for dimension values, and accessed from the R.dimen class.

strings.xml for string values, and accessed from the R.string class.

styles.xml for styles, and accessed from the R.style class.

沒有保存,系統不會知道你已經添加了新控件,新資源,

所以,在每次添加新資源或者更改內容後,ctrl+s保存一下,R.java纔會自動生成相關代碼

 

Android中度量單位含義

dip: device independent pixels(設備獨立像素). 不一樣設備有不一樣的顯示效果,這個和設備硬件有關,通常咱們爲了支持WVGAHVGAQVGA 推薦使用這個,不依賴像素。

dp: 和dip是同樣的

px: pixels(像素). 不一樣設備顯示效果相同,通常咱們HVGA表明320x480像素,這個用的比較多。

pt: point,是一個標準的長度單位,1pt1/72英寸,用於印刷業,很是簡單易用;

sp: scaled pixels(放大像素). 主要用於字體顯示best for textsize

in(英寸):長度單位。

mm(毫米):長度單位。

 

分辨率能夠從顯示分辨率與圖像分辨率兩個方向來分類。

顯示分辨率(屏幕分辨率)是屏幕圖像的精密度,是指顯示器所能顯示的像素有多少。

圖像分辨率則是單位英寸中所包含的像素點數,其定義更趨近於分辨率自己的定義。

單位

標記

說明

毫米

mm(milli meters)

實際的物理測量單位,在屏幕上以毫米爲單位顯示

英寸

in(inch)

實際的物理測量單位,在屏幕上以英寸爲單位顯示,1英寸約爲2.54釐米

像素

px(pixels)

像素是構成數碼影像的基本單元,一般以像素每英寸PPI(pixels per inch)爲單位來表示影像分辨率的大小。

pt(point)

實際的物理測量單位,1點等於1/72英寸,經常使用於印刷業

密度獨立像素

dp(density independed pixels) 

虛擬像素,也就是說每一個設備都有其獨立的像素。

1dp=1*像素密度/160=實際像素數

例如:一個手機的像素密度爲230dpi(嚴格來講是ppi),那麼1dp=1sp=1*320/160=2px.

刻度獨立像素

sp(scale independed pixels)

虛擬像素,實際長度與dp相同,只是常被用於字體的顯示,Android字體大小默認單位爲sp

 

ppiPixel Per Inch每英寸像素數):指每英寸屏幕的像素密度

 

dpi(Dot Per Inch,每英寸點數):指每英打印的點密度

 

若是你以600dpi打印一張150ppi的照片,那麼每一個像素包含16個點。(600 dots/150 "pixels" = 4 rows of 4 dots per "pixel").

Android而言,dpi等價於ppidpi最先是用於印刷行業,跟PPI仍是有本質不一樣的,Android應該是誤用了DPI這個概念。

 

屏幕尺寸是手機屏幕對角線的長度

 

例如:華爲榮耀7的配置以下:

屏幕像素密度=(√1920^2+1080^2)÷5.2424ppi

 

一個像素的尺寸是可變的,屏幕密度有關:

若是像素密度爲72ppi,那麼每英寸裏有72個像素,每像素就是1/72英寸;

若是屏幕精度爲300ppi,每像素就是1/300英寸了;

在一樣尺寸下,例如都是5釐米,300ppi精度的更清晰

 

分辨率能夠從顯示分辨率與圖像分辨率兩個方向來分類。

顯示分辨率(屏幕分辨率)是屏幕圖像的精密度,是指顯示器所能顯示的像素有多少。

圖像分辨率則是單位英寸中所包含的像素點數,其定義更趨近於分辨率自己的定義。

 

精度/分辨率(resolution)是水平像素數*垂直像素數,常見的Android手機分辨率以下:

VGA(Video Graphics Array,即視頻圖形陣列):480*640,標準的視頻接口分辨率

QVGA(Quarterly~):240*320,只有VGA的四分之一

HVGA(Half~):480*320,只有VGA的二分之一,使用的比較少了,開發使用

WVGA(Wide~):480*800

FWVGA(Full Wide~):480*854

 

※ 像素是Android屏幕顯示的默認單位,

 

 

●爲何Androidres文件夾要分別存放mdpildpihdpi文件?

在以前的版本中,只有一個drawable

而從2.1版本之後,res中開始有drawable-mdpidrawable-ldpidrawable-hdpi三個,

這三個主要是爲了支持多分辨率。

drawable- hdpi、drawable- mdpidrawable-ldpi的區別:

(1)drawable-hdpi裏面存放高分辨率的圖片,WVGA (480x800),FWVGA (480x854)分辨率的機型;

(2)drawable-mdpi裏面存放中等分辨率的圖片,HVGA (320x480) 分辨率的機型;

(3)drawable-ldpi裏面存放低分辨率的圖片,QVGA (240x320) 分辨率的機型;

系統會根據機器的分辨率來分別到這幾個文件夾裏面去找對應的圖片。

 

 

具體來講:

ldpi 120dpi如下

mdpi 120dpi ~ 160dpi

hdpi 160dpi ~ 240dpi

xhdpi 240dpi ~ 320dpi

xxhdpi 320dpi ~ 480dpi

xxxhdpi 480dpi ~ 640dpi

 

不一樣分辨率的圖片可同名, 例如:

Android系統定義了四種像素密度:低(120dpi)、中(160dpi)、高(240dpi)和超高(320dpi),它們對應的dppx的係數分別爲0.7511.52,這個係數乘以dp長度就是像素數。

例如界面上有一個長度爲"80dp"的圖片,那麼它在240dpi的手機上實際顯示爲80x1.5=120px,在320dpi的手機上實際顯示爲80x2=160px

若是你拿這兩部手機放在一塊兒對比,會發現這個圖片的物理尺寸"差很少",這就是使用dp做爲單位的效果,見下圖:

 

●對於不一樣像素密度的圖片,Android系統給定了其對應比例和倍數以下

分類目錄

ldpi

mdpi

hdpi

xhdpi

xxhdpi

xxxhdpi

密度(dpi)

~160

~240

~320

~480

~640

  

圖片比例

1.5

2

3

4

6

8

倍數

0.75x

1x

1.5x

2x

3x

4x

 

 

 

●不一樣分辨率手機的比例調查(201211月數據)

 

ldpi

mdpi

hdpi

xhdpi

   

Pequeña

1,7%

 

1%

 

xxhdpi

xxxhdpi

Normal

0,4%

11%

50,1%

25,1%

~640

 

Grande

0,1%

2,4%

 

3,6%

6

8

Extra grande

 

4,6%

   

3x

4x

 

 

 

Java中方法調用方法

例如: f.getToolkit().getScreenSize()

f.getToolkit()獲得一個Toolkit對象

f.getToolkit().getScreenSize() 是Toolkit對象調用getScreenSize(),這個方法是有返回值的。

 

 

 

 

 

 

 

第7章 設計界面佈局

The ViewGroup is the base class for layouts and views containers.

咱們常常編寫Layout文件,經過Layout文件咱們能夠看到全部的View在界面上均佔有一矩形區域,而咱們能夠把這種矩形區域(View)大體分爲兩類,即:

① 單一的矩形區域(View),

② 包含有小矩形區域的大矩形區域(ViewGroup)

這種大小矩形相套的格局自頂向下造成一種樹形結構,咱們能夠將其稱爲View.

下圖是簡略的View樹:

 

 

The standard Layouts (標準佈局類):

Layout

Description

LinearLayout

(Horizontal)

(Vertical)

LinearLayout is a view group that aligns all children in a single direction, vertically or horizontally.

RelativeLayout

RelativeLayout is a view group that displays child views in relative positions.

相對佈局一般有兩種形式,一種是相對於容器而言的,一種是相對於控件而言的。

TableLayout

TableLayout is a view that groups views into rows and columns.

GridLayout

GridLayout uses a grid of infinitely-thin lines to separate its drawing area into: rows, columns, and cells. It supports both row and column spanning, which together allow a widget to occupy a rectangular range of cells that are next to each other.

FrameLayout

The FrameLayout is a placeholder on screen that you can use to display a single view.

AbsoluteLayout

AbsoluteLayout enables you to specify the exact location of its children. Arrange the children views according coordinates x, y.

 

relative layout

 

TableLayout GridLayout

有了TableLayout又搞個GridLayout的緣由以下:

1. TableLayout不能同時向水平和垂直方向作控件的對齊

TableLayout繼承了LinearLayout,所以只能向一個方向作控件的對齊。

 

2.不能跨行跨列

由於TableLayout,不明確指定包含多少行,多少列,而是經過向TableRow裏面添加其餘組件,每添加一個組件該表格就增長一列。

若是向TableLayout裏面添加組件,那麼該組件就直接佔用一行。因此這種方式形成控件不能跨行跨列。

GridLayout,則用columnCount設置列數後,增長的控件在超過列數後自動換行進行排列。

 

The standard Views Containers(視圖容器):

A container is a view used to contain other views.

Container

 

RadioGroup

ListView

GridView

ExpandableListView

ScrollView

HorizontalScrollView

SearchView

TabHost

VideoView

DialerFilter

 

●注意事項

因爲GridLayoutAndroid4.0以後有的新功能,若是要在項目中使用這種佈局,須要把SDK的最低版本指定爲Android4.0API14—)以上。

AndroidManifest.xml中,配置SDK兼容的最低版本和最高版本示例代碼以下:

<uses-sdk

android:minSdkVersion="14"

android:targetSdkVersion="17" />

絕對佈局多用於遊戲開發中,因爲多分辨率兼容麻煩,絕對佈局在Android1.5後被Google棄用,所以應用開發通常狀況下不推薦使用絕對佈局。

 

setContentView( )方法

setContentView(R.layout.main)在Android裏面,這句話是什麼意思?

R.layout.main是個佈局文件即控件都是如何擺放如何顯示的,setContentView就是設置一個Activity的顯示界面,這句話的意思是 設置 這一條語句所在的Activity 採用 R.layout下的main佈局文件進行佈局

 

LayoutParams(佈局參數類)

LayoutParams類的 繼承關係 爲:

Android.View.ViewGroup.LayoutParams.

LayoutParams類至關於一個Layout的信息包,它封裝了Layout的位置、高、寬等信息。假設在屏幕上一塊區域是由一個Layout佔領的,若是將一個View添加到一個Layout中,最好告訴Layout用戶指望的佈局方式,也就是將一個承認的layoutParams傳遞進去。

能夠這樣去形容LayoutParams,在象棋的棋盤上,每一個棋子都佔據一個位置,也就是每一個棋子都有一個位置的信息,如這個棋子在44列,這裏的"44列"就是棋子的LayoutParams

//建立一個線性佈局

    private LinearLayout mLayout;

    mLayout = (LinearLayout) findViewById(R.id.layout);

//如今我要往mLayout裏邊添加一個TextView

//你可能會想直接在佈局文件裏邊配置不就O 了 那是 可是這裏爲了說明問題咱們用代碼實現

    TextView textView = new TextView(Activity01.this);

    textView.setText("Text View " );

//這裏請不要困惑這裏是設置 這個textView的佈局 FILL_PARENT WRAP_CONTENT 和在xml文件裏邊設置是同樣的如

/**<TextView

    android:layout_width="fill_parent"

    android:layout_height="wrap_content"

    android:text="Text View"/>*/

//xml裏邊怎麼配置高寬你們都會的。

//第一個參數爲寬的設置,第二個參數爲高的設置。

    LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(

    LinearLayout.LayoutParams.FILL_PARENT,

    LinearLayout.LayoutParams.WRAP_CONTENT

    );

//調用addView()方法增長一個TextView到線性佈局中

    mLayout.addView(textView, p);

//比較簡單的一個例子

 

●書中169面的main.xml文件編寫完成後, 須要在源文件中進行以下設置:

 

FrameLayout(框架佈局)

框架佈局是最簡單的佈局形式。全部添加到這個佈局中的視圖都以層疊的方式顯示。第一個添加的控件被放在最底層,最後一個添加到框架佈局中的視圖顯示在最頂層,上一層的控件會覆蓋下一層的控件。這種顯示方式有些相似於堆棧。

 

通常不多使用,因此只是做爲一個知識點列出來。借鑑於前人的樣例

 

TabActivity實現多頁顯示效果

http://158067568.iteye.com/blog/941338

 

●探討一下TabActivity

作個假定先: 好比咱們最外面的ActivityMainActivity, 第一個tabFirstActivty, 第二個tabSecondActivity .

相信你們都用過TabActivity, 它是一個特殊的Activity,它特殊的地方在哪裏?有如下幾點爲證:

a. 它看起來違反了Activity的單一窗口的原則。由於它能夠同時加載幾個Activity 當用戶點擊它上面的tab時,就會跳到相應的Activity上面去。

b. 用戶首先進去FirstActivity,而後進去SecondActivity,再點擊返回鍵的時候。它返回的界面不是FirstActivity,而是退出咱們的應用程序。

c. 當用戶在FirstActivity按返回鍵的時候,若是MainActivityFirstActivity經過重寫onKeyDown()方法,那麼收到事件回調的只有FirstActivity

 

(二)TabActivity存在必要性以及google當時的困擾

a. 首先咱們要明白一點,android系統是單窗口系統,不像windows是多窗口的(好比在windows系統上,咱們能夠一邊聊QQ,一邊鬥地主等等)。也就是說,在一個時刻,android裏面只有一個activity能夠顯示給用戶。這樣就大大下降了操做系統設計的複雜性(包括事件派發等等).

b. 可是像TabActivity那種效果又很是必要,由於用戶體驗也比較好。因此我以爲當時google開發人員確定很糾結。。 因而,一個畸形的想法產生了,就是在單窗口系統下加載多個activity,它就是TabActivity

 

TabActivity已通過時,Android4.0 之後直接使用fragment 便可,而最新版的安卓sdk ,一般已經將兼容包配置好了,不過,須要注意的是Eelipse 提醒的時候import 依然會提示老版本的 fragment v4Fragment(version 4 fragment)

一部當心,會選到第一個,程序運行不出來

 

TabActivity圖示

- TabActivity - This is a specialized view that acts as a container for a TabHost (described below).

- TabHost - This is a container for the tabbed UI, hosting two children: a list of tab labels (選項卡標籤) (i.e., tab widget) and a FrameLayout displaying the contents of the Activities or Views - When a tab (選項卡) is selected, it displays either an Activity or a View in the FrameLayout .

 

TabWidget - This control displays a list of tab labels, one for each tab in the TabHost . Each tab in a TabHost is represented by a TabHost.TabSpec object. This object contains the meta-data for each tab. When the user selects a tab, the TabHost responds to the selection by displaying the appropriate tab.

FrameLayout - A tabbed UI must have a FrameLayout contained inside of a TabHost . It is used to display the contents for the tab.

 

TabHost is an old API that has been deprecated by Google. Developers are encouraged to build tabbed applications using the ActionBar.

 

TabSpec(在代碼中實現, 不在xml文件中實現, Spec指的是Specify)

表明了選項卡界面, 添加一個TabSpec便可添加到TabHost;

-- 建立選項卡 : newTabSpec(String tag), 建立一個選項卡;

-- 添加選項卡 : addTab(tabSpec);

 

※ 案例

遠程音樂列表和本地音樂列表爲兩個不一樣的按鈕,在TabActivity中它們同屬於一個TabWidget,

而下面的兩個列表都是在各自的Activity中設置,而後在將每個Activity添加到TabActivityFrameLayout中。

也就是說在TabActivity的佈局文件中必須包含TabWidgetFrameLayout兩種控件。

這裏值得一提的是,必須爲TabActivity的佈局文件的根節點設置爲:TabHost

<?xml version="1.0" encoding="utf-8" ?>

<TabHost xmlns:android="http://schemas.android.com/apk/res/android"

    android:id="@android:id/tabhost"

android:layout_width="fill_parent"

android:layout_height="fill_parent">

<LinearLayout

     android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:padding="5dp">

    <TabWidget android:id="@android:id/tabs"

    android:layout_width="fill_parent"

android:layout_height="wrap_content" />

    <FrameLayout

android:id="@android:id/tabcontent"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:padding="5dp" />

</LinearLayout>

</TabHost>

 

參考閱讀:

咱們在ActionBar中進行Fragment之間的切換:

http://blog.csdn.net/xiaodongvtion/article/details/8775142

 

TabActivity & ActivityGroup & Fragment 比較

Android裏面Tab分頁,經常使用的方法有兩種:

一、採用TabActivityTabHost的結合

二、採用ActivityGroupGridView的結合。

 

※ 若是Tab選項過多,能夠採用Gallery+ActivityGroup結合的實現方式。

 

(2012年的說法)ActivityGroup在實際的開發中是十分常見的,在我使用過的Android應用中,十個應用裏面有九個應用的主界面都是使用ActivityGroup的。

提及ActivityGroup,在國內好像直接使用它開發的並很少,基本都是使用TabActivity,它是ActivityGroup惟一的一個子類。

Android端新浪微博的主界面就是用TabActivity來實現的,還有其它的一些應用也幾乎都用TabActivity來實現。在我眼裏,TabActivityGoogle提供的一個很是失敗的API(至少我如今這麼認爲,下文我會說它失敗在哪裏),但中國幾乎全部的應用都使用TabActivity,我不由在思考這是巧合仍是複製粘貼的產物。

每一個選項卡均可以對應多個子Activity,這個是普通TabActivity作不到的。

TabActivity

ActivityGroup

Fragment

 

LayoutInflater

LayoutInflater這個類的做用相似於findViewById()

不一樣點是

LayoutInflater是用來找res/layout/下的xml佈局文件,而且實例化;

findViewById()是找xml佈局文件下的具體widget控件(如ButtonTextView)

LayoutInflater 是一個抽象類,在文檔中以下聲明:

public abstract class LayoutInflater extends Object

 

LayoutInflater的實例的具體做用:

一、對於一個沒有被載入或者想要動態載入的界面,都須要使用LayoutInflater.inflate()來載入;

二、對於一個已經載入的界面,就可使用Activiyt.findViewById()方法來得到其中的界面元素。

得到 LayoutInflater 實例的三種方式:

LayoutInflater inflater = getLayoutInflater(); //調用ActivitygetLayoutInflater()

 

LayoutInflater localinflater =

(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

 

LayoutInflater inflater = LayoutInflater.from(context);

1 LayoutInflater inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE); 

2 View view = inflater.inflate(R.layout.custom, (ViewGroup)findViewById(R.id.test)); 

3  

4 //EditText editText = (EditText)findViewById(R.id.content);// error  

5  

6 EditText editText = (EditText)view.findViewById(R.id.content);

 

ListActivity

一個含有一個ListView組件的Activity類。

也就是說,若是咱們直接在一個普通的Activity中本身加一個ListView也是徹底能夠取代這個ListActivity的,只是它更方便而已。

package com.teleca;

 

 

Create Table like this put some space before INTEGER ....

 

"CREATE TABLE "+TABLE_NAME+" ("+KEY_ID+" INTEGER PRIMARY KEY AUTOINCREMENT)";

Sqlite中,一個自增加字段定義爲INTEGER PRIMARY KEY AUTOINCREMENT或者INTEGER PRIMARY KEY時 ,那麼在插入一個新數據時,只須要將這個字段的值指定爲NULL,便可由引擎自動設定其值。

相關文章
相關標籤/搜索