黄色网页视频 I 影音先锋日日狠狠久久 I 秋霞午夜毛片 I 秋霞一二三区 I 国产成人片无码视频 I 国产 精品 自在自线 I av免费观看网站 I 日本精品久久久久中文字幕5 I 91看视频 I 看全色黄大色黄女片18 I 精品不卡一区 I 亚洲最新精品 I 欧美 激情 在线 I 人妻少妇精品久久 I 国产99视频精品免费专区 I 欧美影院 I 欧美精品在欧美一区二区少妇 I av大片网站 I 国产精品黄色片 I 888久久 I 狠狠干最新 I 看看黄色一级片 I 黄色精品久久 I 三级av在线 I 69色综合 I 国产日韩欧美91 I 亚洲精品偷拍 I 激情小说亚洲图片 I 久久国产视频精品 I 国产综合精品一区二区三区 I 色婷婷国产 I 最新成人av在线 I 国产私拍精品 I 日韩成人影音 I 日日夜夜天天综合

Android 開發(fā)之深入分析布局文件&又是“Hello W

系統(tǒng) 2292 0

引言

上篇 可以說是一個(gè)分水嶺,它標(biāo)志著我們從Android應(yīng)用程序理論進(jìn)入實(shí)踐,我們拿起手術(shù)刀對(duì)默認(rèn)的“Hello World!”程序進(jìn)行了3個(gè)手術(shù),我們清楚了“Hello world!”是如何實(shí)現(xiàn)顯示在屏幕上的,而且我們知道不僅可以根據(jù)布局文件main.xml來初始化屏幕,還可編程地進(jìn)行。以后基本我們都會(huì)以實(shí)踐的方式來深入Android開發(fā)。我們這次深入分析Android應(yīng)用程序的布局文件,主要內(nèi)容如下:

  • 1、用戶界面及視圖層次
  • 2、Android中布局定義方法
  • 3、編寫XML布局文件及加載XML資源
  • 4、常用布局文件中元素的屬性
    • 4.1、ID屬性
    • 4.2、布局參數(shù)
  • 5、布局位置&大小&補(bǔ)距&邊距
  • 6、又是“Hello World!”
    • 6.1、又是“Hello World!”(一)
    • 6.2、又是“Hello World!”(二)
    • 6.3、又是“Hello World!”(三)

1、用戶界面及視圖層次

在通過“Hello World!”介紹Android中的布局問題之前,不得不先介紹一下Android中的用戶界面,因?yàn)椴季謫栴}也是用戶界面問題之一。在一個(gè)Android應(yīng)用程序中,用戶界面通過 View ViewGroup 對(duì)象構(gòu)建。Android中有很多種Views和ViewGroups,他們都繼承自 View 類。 View 對(duì)象是Android平臺(tái)上表示用戶界面的基本單元。

View 類:

extends Object
implements Drawable.Callback ?? KeyEvent.Callback ?? AccessibilityEventSource

這個(gè)類表示用戶界面組件的基本構(gòu)建塊,一個(gè)View占據(jù)屏幕上的一個(gè)矩形區(qū)域,并負(fù)責(zé)繪圖和事件處理。 View 類是 widgets 的基類, widgets 用于創(chuàng)建交互式UI組件(buttons、text fields等)。 View 類的直接子類 ViewGroup 類是 layouts 的基類, layouts 是不可見的容器用戶保持其他Views或者其他ViewGroups和定義它們的布局屬性。

一個(gè) View 對(duì)象是一個(gè)數(shù)據(jù)結(jié)構(gòu),它的屬性存儲(chǔ)屏幕上一個(gè)特定矩形區(qū)域的 布局參數(shù) 內(nèi)容 。一個(gè) View 對(duì)象處理它自己的測(cè)度、布局、繪圖、焦點(diǎn)改變、滾動(dòng)、鍵/手勢(shì)等與屏幕上矩形區(qū)域的交互。作為用戶界面中的對(duì)象,View也是與用戶交互的一個(gè)點(diǎn)且交互事件接收器。

在Android平臺(tái)上,你定義活動(dòng)的UI使用的View和ViewGroup節(jié)點(diǎn)的層次結(jié)構(gòu)如下圖所示。根據(jù)你的需要這個(gè)層次樹可以是簡(jiǎn)單的或復(fù)雜的,并且你能使用Android預(yù)定義的 widgets layouts 集合,或者使用自定義的Views。

viewgroup

圖1、視圖層次結(jié)構(gòu)

為了將視圖層次樹呈現(xiàn)到屏幕上,你的活動(dòng)必須調(diào)用 setContentView() 方法并且傳遞到根節(jié)點(diǎn)對(duì)象的引用。Android系統(tǒng)接收這個(gè)引用并使用它來驗(yàn)證、測(cè)度、繪制樹。層次的根節(jié)點(diǎn)要求它的孩子節(jié)點(diǎn)繪制它自己——相應(yīng)地每個(gè)試圖組節(jié)點(diǎn)要求調(diào)用自己的孩子視圖去繪制他們自己。子視圖可能在父視圖中請(qǐng)求指定的大小和位置,但是父視圖對(duì)象有最終決定權(quán)(子視圖在哪個(gè)位置及多大)。因?yàn)樗鼈兪前葱蚶L制的,如果元素有重疊的地方,重疊部分后面繪制的將在之前繪制的上面。

2、Android中布局定義方法

布局是一個(gè)活動(dòng)中的用戶界面的架構(gòu),它定義了布局結(jié)構(gòu)且存儲(chǔ)所有顯示給用戶的元素。有兩種方式可以聲明布局,這個(gè)我們?cè)谏衔闹幸呀?jīng)用了(對(duì)應(yīng) 上文 的“Hello World的手術(shù)(二)”、“Hello World的手術(shù)(三)”)。我們?cè)僦販亍⒖偨Y(jié)一下:

  • 方法一、在XML格式的布局文件中聲明UI 。Android提供了簡(jiǎn)易的XML詞匯表對(duì)應(yīng)視圖類和其子類,諸如 widgets layouts
  • 方法二、在運(yùn)行時(shí)實(shí)例化布局元素 。可以編程地創(chuàng)建View和ViewGroup對(duì)象,并操作他們的屬性。

Android框架給我們靈活地使用這兩個(gè)方法之一或兩個(gè)聲明和管理你的應(yīng)用程序的UI。例如,你可以用XML格式的布局文件定義應(yīng)用程序默認(rèn)的布局,包括將顯示在屏幕的元素和屬性。然后你可以編程地修改屏幕上對(duì)象的狀態(tài),包括定義在XML文件中的元素。

最常用的是方法一,即用一個(gè)XML的布局文件定義自己的布局和表達(dá)層次視圖。XML提供一種直觀的布局結(jié)構(gòu),類似HTML。XML中的每個(gè)元素是一個(gè)View或者ViewGroup對(duì)象(或繼承自他們的對(duì)象)。View對(duì)象是樹中的葉子,ViewGroup對(duì)象是樹中的分支,這點(diǎn)可以從上面的視圖層次樹中可以看出。

在XML布局文件中聲明UI的優(yōu)點(diǎn)是:使 應(yīng)用程序的界面 控制它行為的代碼 更好地分離了。UI描述在應(yīng)用程序代碼之外,這意味著你可以修改或調(diào)整它而不用修改你的源碼并重新編譯。例如,你可以為不同的屏幕方向、不同的屏幕大小、不同的語(yǔ)言創(chuàng)建XML布局文件。此外,在XML中聲明布局更易地可視化你的UI結(jié)構(gòu),因此更容易調(diào)試問題。

一個(gè)元素XML元素的名字對(duì)應(yīng)到一個(gè)Java類,因此一個(gè) <TextView> 元素在你的UI中創(chuàng)建一個(gè)TextView,一個(gè) <linearLayout> 元素創(chuàng)建一個(gè)LinearLayout的視圖組。當(dāng)你加載一個(gè)布局資源時(shí),Android系統(tǒng)初始化這些運(yùn)行時(shí)對(duì)象,對(duì)應(yīng)你的布局中的元素。XML元素的屬性對(duì)應(yīng)到一個(gè)Java類的方法。

3、編寫XML布局文件及加載XML資源

使用Android的XML詞匯,我們可以快速地設(shè)計(jì)UI布局及包含的屏幕元素,就像web頁(yè)面的HTML。每個(gè)布局文件必須包含一個(gè)根元素,根元素必須是一個(gè)View或ViewGroup對(duì)象。一旦你已經(jīng)定義了根元素,你可以添加額外的 layout 對(duì)象或 widgets 作為子元素,逐步地構(gòu)建一個(gè)視圖層次定義你的布局。例如,下面的XML布局文件使用了縱向的LinearLayout保存一個(gè)TextView和一個(gè)Button。

<? xml version="1.0" encoding="utf-8" ?>
< LinearLayout xmlns : android = "http://schemas.android.com/apk/res/android"
????????????? android : layout_width = "fill_parent"
????????????? android : layout_height = "fill_parent"
????????????? android : orientation = "vertical" >
??? < TextView android : id = "@+id/text"
????????????? android : layout_width = "wrap_content"
????????????? android : layout_height = "wrap_content"
????????????? android : text = "Hello, I am a TextView" />
??? < Button android : id = "@+id/button"
??????????? android : layout_width = "wrap_content"
??????????? android : layout_height = "wrap_content"
??????????? android : text = "Hello, I am a Button" />
</ LinearLayout >

布局文件以.xml為擴(kuò)展名,保存在 res/layout/ 下面,它將會(huì)被正確地編譯。我們已經(jīng)定義好了布局文件,那它是怎么被加載的呢?當(dāng)我們編譯應(yīng)用程序時(shí),每個(gè)XML布局文件被編譯成一個(gè)View資源。我們應(yīng)該在應(yīng)用程序代碼中加載布局資源,在 Activity.onCreate() 回調(diào)中通過調(diào)用 setContentView() 實(shí)現(xiàn),以 R.layout.layout_ file_name 形式傳遞給它布局資源的引用。例如,如果你的XML布局保存為main_layout.xml,你應(yīng)該這樣加載它:
public void onCreate(Bundle savedInstanceState) {
??? super .onCreate(savedInstanceState);
??? setContentView.(R.layout.main_layout);
}
活動(dòng)中的 onCreate() 回調(diào)方法,當(dāng)你的活動(dòng)啟動(dòng)時(shí)被Android框架調(diào)用(詳見 Android 開發(fā)之旅:組件生命周期(一) ,詳細(xì)介紹了活動(dòng)組件的生命周期)。

4、常用布局文件中元素的屬性

每個(gè)View和ViewGroup對(duì)象支持他們自己的各種XML屬性。一些屬性特定于一個(gè)View對(duì)象(例如,TextView支持textSize屬性),但是這些屬性也被繼承自這個(gè)類的任何View對(duì)象繼承。一些屬性對(duì)所有View對(duì)象可用,因?yàn)樗麄儚母? View 類繼承(諸如id屬性)。并且,其他屬性被考慮為“布局參數(shù)”,這些屬性描述特定View對(duì)象的特定布局方向,由對(duì)象的父ViewGroup對(duì)象定義。

4.1、ID屬性

每個(gè)View對(duì)象都有一個(gè)關(guān)聯(lián)的ID,來唯一標(biāo)識(shí)它。當(dāng)應(yīng)用程序被編譯時(shí),這個(gè)ID作為一個(gè)整數(shù)引用。但是ID通常是在布局XML文件中作為字符串分配的,作為元素的id屬性。這個(gè)XML屬性對(duì)所有的View對(duì)象可用且會(huì)經(jīng)常用到。XML中的ID語(yǔ)法如下:

android:id=" @+id/my_button "

字符串前的 @符號(hào)表示XML解析器應(yīng)該解析和擴(kuò)展剩下的ID字符串 ,并把它作為ID資源。 +符號(hào)表示這是一個(gè)新的資源名字,它必須被創(chuàng)建且加入到我們的資源 (R.java文件,R是Resource)。Android框架提供一些其他的ID資源。當(dāng)引用一個(gè) Android資源ID時(shí),你不需要+符號(hào),但是你必須添加android包名字空間,如下:

android:id=" @android:id/empty "

為了創(chuàng)建視圖和從應(yīng)用程序引用他們,通常的模式是:

  1. 首先在布局文件中定義一個(gè)視圖/構(gòu)件對(duì)象并分配一個(gè)唯一的ID:
    < Button android : id = "@+id/my_button"
    ??????? android : layout_width = "wrap_content"
    ??????? android : layout_height = "wrap_content"
    ??????? android : text = "@string/my_button_text" />
  2. 然后創(chuàng)建一個(gè)視圖對(duì)象實(shí)例并從布局中獲取它(典型的是在 onCreate() 方法中):
    Button myButton = (Button) findViewById(R.id.my_button);

4.2、布局參數(shù)

名為 layout_ something 的XML布局屬性,為視圖定義適合于它所駐留的ViewGroup的布局參數(shù)。每個(gè)ViewGroup類實(shí)現(xiàn)一個(gè)擴(kuò)展自 ViewGroup.LayoutParams 的嵌套類。這個(gè)子類包含為每個(gè)子視圖定義 大小 位置 的屬性類型,以適合于該視圖組。如下圖所示,父視圖組為每個(gè)子視圖定義布局參數(shù)(包括子視圖組)。

layoutparams ???
圖2、布局參數(shù)

注意每個(gè)LayoutParams子類有它自己的設(shè)置值的語(yǔ)法。每個(gè)子元素必須定義適合于它父視圖的LayoutParams,雖然它可能也為自己的子視圖定義不同LayoutParams。

所有的視圖組包括寬帶和高度( layout_width layout_height ),并且每個(gè)視圖要求要定義它們。許多LayoutParams也包括可選的邊距和邊界。你可以指定寬度和高度的具體值,雖然你可能并不想這樣做。更多地你將告訴視圖它的大小依據(jù)它內(nèi)容要求或跟父視圖組所允許的一樣大(分別用 wrap_content fill_parent 值)。

5、布局位置&大小&補(bǔ)距&邊距

視圖的幾何形狀是一個(gè)矩形。視圖的位置表示為一個(gè)left和top的坐標(biāo)對(duì),尺寸(dimensions)表示為寬度和高度。位置和尺寸的單位是像素(pixel)。

可以通過調(diào)用 getLeft() getTop() 檢索視圖的位置。前者返回視圖矩形坐標(biāo)的left或x,后者返回視圖矩形坐標(biāo)的right或y。這些方法返回相對(duì)于與其父視圖的相對(duì)位置,例如當(dāng) getLeft() 返回20,即認(rèn)為視圖到其直接父視圖的左邊距離為20像素。

此外,提供了一些額外的方法如 getRight() getButtom() 避免不必要的計(jì)算。這些方法返回視圖坐標(biāo)的右邊距和底邊距。例如,調(diào)用 getRight() 等同于下面的計(jì)算: getLeft() + getWidth()

視圖的大小(size)也表示為寬度和高度,但跟上面尺寸(dimensions)是區(qū)別的。上面的尺寸定義視圖想在父視圖中占多大,視圖的尺寸可以通過 getMeasureWidth() getMeasureHeight() 獲得。而視圖的大小(size)則表示視圖在屏幕上的實(shí)際大小,他們的值可以跟視圖尺寸的不一樣,但也不是非得這樣。視圖的大小可以通過 getWidth() getHeight() 獲得。

為了估量視圖的尺寸,必須考慮它的補(bǔ)距(padding,即視圖內(nèi)容與視圖邊框的距離)。補(bǔ)距以像素表示視圖的left、top、right和bottom部分的空白。補(bǔ)距可以用來按特定數(shù)量的像素偏移視圖內(nèi)容。例如,左補(bǔ)距是2將輸出內(nèi)容離左邊框2像素。補(bǔ)距可以通過 setPadding(int, int, int, int) 方法設(shè)置和通過 getPaddingLeft() getPaddingRight() getPaddingTop() getPaddingBottom() 來查詢。雖然一個(gè)視圖可以定義補(bǔ)距,但是它不支持邊距(margins)。然而,視圖組支持邊距。

6、又是“Hello World!”

下面我們通過幾個(gè)實(shí)驗(yàn)來驗(yàn)證和加深上述關(guān)于布局文件理解。

6.1、又是“Hello World!”(一)

驗(yàn)證名為 layout_ something 的XML布局屬性,用 layout_width layout_height 定義Button的寬度和高度,這兩個(gè)屬性也是每個(gè)視圖對(duì)象都必須要聲明定義的。驗(yàn)證wrap_content與fill_parent的區(qū)別,其實(shí)區(qū)別從他們的單詞組成就可以看出:wrap——包,包裹等而content——內(nèi)容,則wrap_content表示視圖對(duì)象的高度/寬度正好包住內(nèi)容;fill——填充等而parent——父,則fill_parent表示填滿父視圖。

實(shí)驗(yàn)設(shè)置為:在布局資源文件中定義兩個(gè)Button,id分別為button1、button2,button1的寬度和高度屬性都是wrap_content,button2的寬度和高度屬性都是fill_parent。main.xml文件代碼如下:
<? xml version="1.0" encoding="utf-8" ?>
< LinearLayout xmlns : android = "http://schemas.android.com/apk/res/android"
????????????? android : layout_width = "fill_parent"
????????????? android : layout_height = "fill_parent"
????????????? android : orientation = "vertical" >
??? < Button android : id = "@+id/button1"
??????????? android : layout_width = "wrap_content"
??????????? android : layout_height = "wrap_content"
??????????? android : text = "Hello, I am a Button" />
??? < Button android : id = "@+id/button2"
??? android : layout_width = "fill_parent"
??? android : layout_height = "fill_parent"
??? android : text = "Hello, I am a Button"
??? />
</ LinearLayout >
而HelloWorld.java文件代碼為:
package skynet.com.cnblogs.www;

import android.app.Activity;
import android.os.Bundle;
import android.widget.*; //注意:導(dǎo)入此包,或者是android.widget.Button;

public class HelloWorld extends Activity {
??? private CharSequence text=" new Hello! ";

/** Called when the activity is first created. */
??? @Override
??? public void onCreate(Bundle savedInstanceState) {
??????? super .onCreate(savedInstanceState);
??????? setContentView(R.layout.main);
??? }
}
運(yùn)行可以得到如下圖結(jié)果:

又見HelloWorld1

圖3、驗(yàn)證 驗(yàn)證名為 layout_ something 的XML布局屬性

明顯可以看出button1的大小是剛好包住內(nèi)容“Hello,I am a Button”,而button2的大小則是填滿父視圖的大小。

6.2、又是“Hello World!”(二)

接下來我們視圖對(duì)象的通用屬性ID及再次驗(yàn)證定義布局的兩種方式。(關(guān)于ID屬性——首先在布局文件中定義一個(gè)視圖/構(gòu)件對(duì)象并分配一個(gè)唯一的ID,然后創(chuàng)建一個(gè)視圖對(duì)象實(shí)例并從布局中獲取它(典型的是在 onCreate() 方法中))。

屬性實(shí)驗(yàn)設(shè)置為:基本跟上面一樣,但是我們要編程地修改button1的text屬性。main.xml布局文件跟上面一樣,而主要是HelloWorld.java文件不一樣,它的代碼如下:
package skynet.com.cnblogs.www;

import android.app.Activity;
import android.os.Bundle;
//import android.widget.*;
import android.widget.Button;

public class HelloWorld extends Activity {
??? private CharSequence text=" new Hello! ";

/** Called when the activity is first created. */
??? @Override
??? public void onCreate(Bundle savedInstanceState) {
??????? super .onCreate(savedInstanceState);
??????? setContentView(R.layout.main);
??????? Button myButton=(Button)findViewById(R.id.button2);
??????? myButton.setText(text);

??? }
}
上面紅色粗體的兩行代碼就是編程地改變button2的text屬性,這體現(xiàn)了Android框架給我們靈活地使用上面兩個(gè)方法之一或兩個(gè)聲明和管理你的應(yīng)用程序的UI。運(yùn)行結(jié)果如下圖所示:

又見HelloWorld2

圖4、驗(yàn)證視圖對(duì)象的通用屬性Id的常用模式及編程地改變定義在XML布局文件中的Button的屬性

6.3、又是“Hello World!”(三)

?

?

驗(yàn)證視圖對(duì)象的布局位置&大小&補(bǔ)距,實(shí)驗(yàn)設(shè)置為:在實(shí)驗(yàn)一的基礎(chǔ)上在main.xml中修改button1的布局位置、大小、補(bǔ)距等屬性。修改后的mian.xml文件如下:
<? xml version="1.0" encoding="utf-8" ?>
< LinearLayout xmlns : android = "http://schemas.android.com/apk/res/android"
????????????? android : layout_width = "fill_parent"
????????????? android : layout_height = "fill_parent"
????????????? android : orientation = "vertical" >
??? < Button android : id = "@+id/button1"
??????????? android : layout_width = "wrap_content"
??????????? android : layout_height = "wrap_content" ???????????
??????????? android : text = "Hello, I am a Button"
??????????? android : width = "250dp"
??????????? android : height = "80dp"
??????????? android : padding = "20dp"
??????????? android : layout_margin = "20dp"

??????????? />
??? < Button android : id = "@+id/button2"
??? android : layout_width = "fill_parent"
??? android : layout_height = "fill_parent"
??? android : text = "Hello, I am a Button"
??? />
</ LinearLayout >
運(yùn)行后結(jié)果如下所示:

又見HelloWorld3

圖5、 驗(yàn)證視圖對(duì)象的布局位置&大小&補(bǔ)距

NOTE:上述代碼中布局位置&大小&補(bǔ)距的單位(如width="250dp")。單位可以為px、in、mm、pt、dp、sp。

  • px:pixels(像素)——對(duì)應(yīng)屏幕上實(shí)際的像素
  • in:inches(英寸)——基于物理屏幕的大小
  • mm:millimeters(毫米)——基于物理屏幕的大小
  • pt:points(點(diǎn))——英寸的1/72,基于基于物理屏幕的大小
  • dp:density-independent pixels(獨(dú)立于密度的像素)——一個(gè)抽象的基于物理屏幕密度的單位。這些單位是相對(duì)于一個(gè)160dpi的屏幕,所有一個(gè)dp是160dpi屏幕上的一個(gè)點(diǎn)。dp到px的轉(zhuǎn)換比率根據(jù)屏幕密度改變,但不一定是成正比。
  • sp:scale-independent pixels(規(guī)模獨(dú)立像素)——類似于dp單位,但是它也受用戶字體大小設(shè)置的影響。當(dāng)你指定字體大小時(shí)使用它,因?yàn)樗麄儗⒏鶕?jù)屏幕和用戶設(shè)置調(diào)整。

Android 開發(fā)之深入分析布局文件&又是“Hello World!”


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論