UI開發
先理清一些UI概念: view、widget、control:這三個名詞其實沒有什麼區別,都是一個UI元素,例如一個button。Container(容器):包含其他view,例如grid可以認為是容器,它有cell,每個cell可以是一個view。Layout:
對容器們和view們的排版,可以包含其他layout。
Android提供常用的UI(例如文字框)以及適合行動裝置的控制,基礎類為android.view.View和android.view.ViewGroup。從名字中很容易看出,後者也是view,但是包含其他view,它是layout的基類,而layout本身也是一個container。
在Android中建立UI,可以通過代碼,也可以通過XML檔案,也可以兩者相結合。我們以一個簡單例子來看看這三種情況。
方式一:通過XML檔案
這種方式在之前學習資源時已經涉及。我們的目標很簡單,通過xml定義一個layout,這個layout裡面有兩個子layout,分別為nameContainer和addressContainer。nameContainer由兩個view組成,採用水平排放的方式,而addressContainer也有兩個view組成,採用垂直擺放的方式。,很簡單。
<?xml version="1.0" encoding="utf-8"?>
<!-- Root view : parentContainer -->
<LinearLayout xmlns:android=http://schemas.android.com/apk/res/android
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<!-- name Container -->
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Name: "/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello Android"/>
</LinearLayout>
<!-- address Container -->
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Address: "/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Earth, Solar, Galaxy"/>
</LinearLayout>
</LinearLayout>
這個xml的位於/res/layout目錄下,名字為ui_basic.xml,我們在代碼中通過setContentView(R.layout.ui_basic); 對其進行調用。
方式二:通過代碼
//在這個小例子中,我們不能使用xml,而是完全對同代碼來實現介面
public class UiBasicCodeTest extends Activity{
private LinearLayout nameContainer = null;
private LinearLayout addressContainer = null;
private LinearLayout parentContainer = null;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
createNameContainer(); //實現name Container,內含2個水平擺放的view
createAddressContainer(); //實現address Container,內含2個垂直擺放的view
createParentContainer(); //實現parentContainer,內含nameAddress和addressContain
setContentView(parentContainer);//通過setContentView來在activity中顯示root view,root view對自己進行渲染,發現有兩個child,這兩個child對自己渲染,如果有children,再一步一步解析下去。
}
//實現name Container
private void createNameContainer(){
nameContainer = new LinearLayout(this);
//layout帶有布局功能,例如設定橫排/豎排,可以包含view,也可以包括其他layout,所以它同時也是一個容器。
//在Android學習筆記系列中,我們使用FILL_PARENT,包括在xml中使用fill_parent,在API Level 8(Android 2.2)後,改為match_parent
nameContainer.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT));
nameContainer.setOrientation(LinearLayout.HORIZONTAL);
//設定內部的view,並放入容器或layout
TextView nameLb = new TextView(this);
nameLb.setText("Name: ");
TextView nameValue = new TextView(this);
nameValue.setText("Hello World");
nameContainer.addView(nameLb);
nameContainer.addView(nameValue);
}
//實現address Container,和name Container相似,不同是改為垂直擺放
private void createAddressContainer(){
addressContainer = new LinearLayout(this);
addressContainer.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT));
addressContainer.setOrientation(LinearLayout.VERTICAL);
TextView addressLb = new TextView(this);
addressLb.setText("Address: ");
TextView addressValue = new TextView(this);
addressValue.setText("Guangzhou, Guangdong , China");
addressContainer.addView(addressLb);
addressContainer.addView(addressValue);
}
//實現root view ,和前面兩個container相似,不同是addView不是加入普通的view,而是加入layout
private void createParentContainer(){
parentContainer = new LinearLayout(this);
parentContainer.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));
parentContainer.setOrientation(LinearLayout.VERTICAL);
parentContainer.addView(nameContainer);
parentContainer.addView(addressContainer);
}
}
方式三:XML+代碼
實際上,我們真正編程時會採用XML+代碼的方式,將UI的設計交給XML,而將涉及動態變化的的內容交給代碼。在小例子中,很明顯,三個layout的架構,渲染,排版是固定的,而部分的textview內容也是固定的,例如“Name : ”和“Address : ”,這些適合通過XML來設定,用XML還有一個好處,可能根據使用者系統語言設定提供不同內容,具體參見。而具體的名字和地址內容,採用代碼方式。
相關的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" >
<!-- name Container -->
<LinearLayout android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ui_basic_name"/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/ui_name"/>
</LinearLayout>
<!-- address Container -->
<LinearLayout android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/ui_basic_address"/>
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/ui_address"/>
</LinearLayout>
</LinearLayout>
對應的代碼如下:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//我們要注意順序,必須先setContentView(),才能通過findViewById()來擷取view的對象,否則會出現NullPointerException的錯誤
setContentView(R.layout.ui_basic_recommend);
TextView nameValue = (TextView)findViewById(R.id.ui_name);
nameValue.setText("Data");
TextView addressValue = (TextView)findViewById(R.id.ui_address);
addressValue.setText("Spaceship Enterprise");
}
相關連結:
我的Android開發相關文章