## 第三天.UI事件處理與布局管理 ##
### 2.1View與ViewGroup ###
#### 2.1.1 Android界面元素 ####
1. View: 視圖組件
2. Layout: 布局組件
3. Wigets: UI元素
4. Menus: 菜單
#### 2.1.2認識View ####
1. 所有高級UI組件都繼承View類而實現的
2. 一個View在屏幕上占據一塊矩形區域
3. 負責渲染
4. 負責處理發生的事件
5. 設置是否可見
6. 設置是否可以獲得焦點等
#### 2.1.3 認識ViewGroup ####
1. ViewGroup對象是android.view.ViewGroup實例
2. ViewGroup是View的容器
3. 負責對添加進ViewGroup的View進行布局
4. 一個ViewGroup可以加入到另一個ViewGroup
#### 2.1.4 View與ViewGroup的關系 ####

### 2.2事件處理機制 ###
控件事件通過設置其控件的監聽器來監聽并處理事件
+ 按鍵按下事件:通過重寫onKeyDown方法
+ 按鍵彈起事件:通過重寫onKeyUp方法
+ 觸筆點擊事件:通過實現onTouchEvent方法
其他事件參考相應UI組件的Demo!!
#### 2.2.1 Toast控件 ####
在視圖中給用戶顯示的短小的提示消息。
```
Toast.makeText(this, string, Toast.LENGTH_SHORT).show();
```
+ LENGTH_LONG:長時間顯示
+ LENGTH_SHORT:短時間顯示
#### 2.2.2事件處理Demo ####
```
public class Activity01 extends Activity
{
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//獲得Button對象
Button button_ok = (Button) findViewById(R.id.ok);
//設置Button控件監聽器
button_ok.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v)
{
//這里處理事件
DisplayToast("點擊了OK按鈕");
}
});
}
```
```
/* 按鍵按下所觸發的事件 */
public boolean onKeyDown(int keyCode, KeyEvent event)
{
switch (keyCode)
{
case KeyEvent.KEYCODE_DPAD_CENTER:
DisplayToast("按下:中鍵");
break;
case KeyEvent.KEYCODE_DPAD_UP:
DisplayToast("按下:上方向鍵");
break;
case KeyEvent.KEYCODE_DPAD_DOWN:
DisplayToast("按下:下方向鍵");
break;
case KeyEvent.KEYCODE_DPAD_LEFT:
DisplayToast("按下:左方向鍵");
break;
case KeyEvent.KEYCODE_DPAD_RIGHT:
DisplayToast("按下:右方向鍵");
break;
}
return super.onKeyDown(keyCode, event);
}
```
```
/* 按鍵彈起所觸發的事件 */
public boolean onKeyUp(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_CENTER:
DisplayToast("彈起:中鍵");
break;
case KeyEvent.KEYCODE_DPAD_UP:
DisplayToast("彈起:上方向鍵");
break;
case KeyEvent.KEYCODE_DPAD_DOWN:
DisplayToast("彈起:下方向鍵");
break;
case KeyEvent.KEYCODE_DPAD_LEFT:
DisplayToast("彈起:左方向鍵");
break;
case KeyEvent.KEYCODE_DPAD_RIGHT:
DisplayToast("彈起:右方向鍵");
break;
}
return super.onKeyUp(keyCode, event);
}
public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
return super.onKeyMultiple(keyCode, repeatCount, event);
}
```
```
/* 觸筆事件 */
public boolean onTouchEvent(MotionEvent event)
{
int iAction = event.getAction();
if (iAction == MotionEvent.ACTION_CANCEL ||
iAction == MotionEvent.ACTION_DOWN ||
iAction == MotionEvent.ACTION_MOVE)
{
return false;
}
//得到觸筆點擊的位置
int x = (int) event.getX();
int y = (int) event.getY();
DisplayToast("觸筆點擊坐標:("+Integer.toString(x)+","+Integer.toString(y)+")");
return super.onTouchEvent(event);
}
/* 顯示Toast */
public void DisplayToast(String str)
{
Toast.makeText(this, str, Toast.LENGTH_SHORT).show();
}
}
```
詳情請參考DEMO
### 2.3 布界面布局方式 ###
+ LinearLayout(線性布局)
+ AbsoluteLayout(絕對布局)
+ RelativeLayout(相對布局)
+ TableLayout(表格布局)
+ FrameLayout(框架布局)
#### 2.3.1LinearLayout(線性布局) ####
是常用的布局之一
一個組件一行的形式顯示出來
分垂直(vertical)與水平(horizontal)兩種。
**main.xml: vertical**
```
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:text="第一行” android:gravity="center_vertical” android:textSize="15pt"
android:background="#aa0000” android:layout_width="fill_parent"
android:layout_height="wrap_content” android:layout_weight="1"/>
<TextView
android:text="第二行” android:textSize="15pt” android:gravity="center_vertical"
android:background="#00aa00” android:layout_width="fill_parent"
android:layout_height="wrap_content” android:layout_weight="1"/>
<TextView
android:text="第三行” android:textSize="15pt” android:gravity="center_vertical"
android:background="#0000aa” android:layout_width="fill_parent"
android:layout_height="wrap_content” android:layout_weight="1"/>
<TextView
android:text="第四行” android:textSize="15pt” android:gravity="center_vertical"
android:background="#aaaa00” android:layout_width="fill_parent"
android:layout_height="wrap_content” android:layout_weight="1"/>
</LinearLayout>
```
**main.xml: horizontal**
```
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:text="第一列” android:gravity="center_horizontal"
android:background="#aa0000” android:layout_width="wrap_content"
android:layout_height="fill_parent” android:layout_weight="1"/>
<TextView
android:text="第二列” android:gravity="center_horizontal"
android:background="#00aa00” android:layout_width="wrap_content"
android:layout_height="fill_parent” android:layout_weight="1"/>
<TextView
android:text="第三列” android:gravity="center_horizontal"
android:background="#0000aa” android:layout_width="wrap_content"
android:layout_height="fill_parent” android:layout_weight="1"/>
<TextView
android:text="第四列” android:gravity="center_horizontal"
android:background="#aaaa00” android:layout_width="wrap_content"
android:layout_height="fill_parent” android:layout_weight="1"/></LinearLayout>
```
#### 2.3.2AbsoluteLayout(絕對布局) ####
絕對布局根據設定好的坐標進行定位顯示
AbsoluteLayout兩個重要的屬性:
+ android:layout_x 組件在屏幕中的X坐標
+ android:layout_y 組件在屏幕中的Y坐標
#### 2.3.3RelativeLayout(相對布局) ####
是按照相對某個組件的位置來進行布局,也就是說參考某個組件,置于此組件的上、下、左、右
其中幾個重要的屬性:
+ android:layout_below=“組件ID” 在某組件下面
+ android:layout_above=“組件ID” 在某組件上面
+ android:layout_toRightOf=“ID” 在某組件右邊
+ android:layout_toLeftOf=“ID” 在某組件左邊
```
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent” android:layout_height="fill_parent“>
<TextView android:id="@+id/label"
android:layout_width="fill_parent” android:layout_height="wrap_content"
android:text="請輸入:"/>
<EditText android:id="@+id/entry"
android:layout_width="fill_parent” android:layout_height="wrap_content"
android:background="@android:drawable/editbox_background"
android:layout_below="@id/label"/>
<Button android:id="@+id/ok"
android:layout_width="wrap_content” android:layout_height="wrap_content"
android:layout_below="@id/entry” android:layout_alignParentRight="true"
android:layout_marginLeft="10dip” android:text="確定" />
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content” android:layout_toLeftOf="@id/ok"
android:layout_alignTop="@id/ok” android:text="取消" />
</RelativeLayout>
```
RelativeLayout Demo
#### 2.3.4TableLayout(表格布局) ####
是比較常用的布局,它是按照表格的方式來布局整個畫面的
TableRow:TableLayout中需要嵌入行,然后將組件置于TableRow中才能顯示成Table的形式
幾個重要的屬性:
+ android:layout_weight:比重
+ TableRow:行
```
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:stretchColumns="1">
<TableRow>
<TextView
android:layout_column="1” android:text="打開...” android:padding="3dip" />
<TextView
android:text="Ctrl-O” android:gravity="right” android:padding="3dip" />
</TableRow>
<TableRow>
<TextView
android:layout_column="1” android:text="保存...” android:padding="3dip" />
<TextView
android:text="Ctrl-S” android:gravity="right” android:padding="3dip" />
</TableRow>
<TableRow>
<TextView
android:layout_column="1” android:text="另存為...” android:padding="3dip" />
<TextView
android:text="Ctrl-Shift-S” android:gravity="right” android:padding="3dip" />
</TableRow>
<View
android:layout_height="2dip"
android:background="#FF909090" />
<TableRow>
<TextView android:text="*” android:padding="3dip" />
<TextView
android:text="導入...” android:padding="3dip" />
</TableRow>
<TableRow>
<TextView android:text="*” android:padding="3dip" />
<TextView android:text="導出...” android:padding="3dip" />
<TextView android:text="Ctrl-E” android:gravity="right” android:padding="3dip" />
</TableRow>
<View
android:layout_height="2dip” android:background="#FF909090" />
<TableRow>
<TextView
android:layout_column="1” android:text="退出"
android:padding="3dip" />
</TableRow>
</TableLayout>
```
TableLayout Demo
#### 2.3.5FrameLayout(框架布局) ####
是一個比較特殊的布局
此布局一般放一個組件,并且這個組件是靠左上角顯示,
如果加入多個組件,那將會顯示最上層的一個組件。
```
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="center"
android:src="@drawable/golden_gate"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="20dip"
android:layout_gravity="center_horizontal|bottom"
android:padding="12dip"
android:background="#AA000000"
android:textColor="#ffffffff"
android:text="Golden Gate"
/>
</FrameLayout>
```
FrameLayout Demo
#### 2.3.6布局之間的關系 ####
LinearLayout、AbsoluteLayout、RelativeLayout、FrameLayout均是ViewGroup的子類
TableLayout則是LinearLayout子類,如果TableLayout中的組件沒有放入TableRow中的話,那么就會按照LinearLayout顯示
在Android中,布局是可以相互嵌套的,比如LinearLayout中能夠嵌入TableLayout一樣
### 2.4 樣式和主題(style&theme) ###
android中的樣式和CSS樣式作用相似,都是用于為界面元素定義顯示風格,它是一個包含一個或者多個view控件屬性的集合。如:需要定義字體的顏色和大小。
在CSS中是這樣定義的:
```
<style>
.lxt{COLOR:#0000CC;font-size:18px;}
</style>
```
可以像這樣使用上面的css樣式:<div class=“lxt">lxt008</div>
在Android中可以這樣定義樣式:
在res/values/styles.xml文件中添加以下內容
```
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name=“lxt”> <!-- 為樣式定義一個全局唯一的名字-->
<item name="android:textSize">18px</item> <!-- name屬性為樣式要用在的View控件持有的屬性 -->
<item name="android:textColor">#0000CC</item>
</style>
</resources>
```
在layout文件中可以像下面這樣使用上面的android樣式:
```
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" ....>
<TextView style="@style/lxt"
..... />
</LinearLayout>
```
<style>元素中有一個parent屬性。這個屬性可以讓當前樣式繼承一個父樣式,當前樣式可以繼承到父樣式的值。當然,如果父樣式的值不符合你的需求,你也可以對它進行修改,如下:
```
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name=“lxt">
<item name="android:textSize">18px</item> <!-- name屬性為樣式要用在的View控件持有的屬性 -->
<item name="android:textColor">#0000CC</item>
</style>
<style name="sublxt" parent="@style/lxt">
<item name="android:textColor">#FF0000</item>
</style>
</resources>
```
android中主題也是用于為應用定義顯示風格,它的定義和樣式的定義相同,如下:
```
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name=“lxtTheme">
<item name=“android:windowNoTitle”>true</item> <!– 沒標題 ?
<item name=“android:windowFullscreen”>?android:windowNoTitle</item> <!– 全屏顯示 ?
</style>
</resources>
```
上面“?android:windowNoTitle”中的問號用于引用在當前主題中定義過的資源的值。
下面代碼顯示在AndroidManifest.xml中如何為應用設置上面定義的主題:
```
<application android:icon="@drawable/icon" android:label="@string/app_name"
android:theme="@style/lxtTheme">
......
</application>
```
除了可以在AndroidManifest.xml中設置主題,同樣也可以在代碼中設置主題,如下:
```
setTheme(R.style.lxtTheme);
```
盡管在定義上,樣式和主題基本相同,但是它們使用的地方不同。樣式用在單獨的View,如:EditText、TextView等;主題通過AndroidManifest.xml中的<application>和<activity>用在整個應用或者某個 Activity,主題對整個應用或某個Activity存在全局性影響。如果一個應用使用了主題,同時應用下的view也使用了樣式,那么當主題與樣式屬性發生沖突時,樣式的優先級高于主題。
另外android系統也定義了一些主題,例如:<activity android:theme=“@android:style/Theme.Dialog”>,該主題可以讓Activity看起來像一個對話框,如果需要查閱這些主題,可以在文檔的reference:android-->R.style 中查看。
[源代碼下載](http://www.apkbus.com/android-83236-1-1.html)