幀布局(FrameLayout)直接繼承了ViewGroup組件;
幀版面配置容器為每一個加入其中的組件都建立了一個空白的地區,這個地區我們稱之為一幀,所有每個組件都佔據一幀,這些都會根據gravity屬性執行自動對齊。
FrameLayout的常用XML屬性及相關的方法:
| XML屬性 |
相關方法 |
說明 |
| android:foreground |
setForeground(Drawable) |
設定該幀版面配置容器的前景映像 |
| android:foregroundGravity |
setForegroundGravity(int) |
定義繪製前景映像的gracity屬性 |
下面用一個霓虹燈效果的例子來看看幀布局的效果:
layout/main.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" 4 android:layout_width="fill_parent" 5 android:layout_height="fill_parent" 6 > 7 <!-- 依次定義7個TextView,先定義的TextView位於底層 8 後定義的TextView位於上層 --> 9 <TextView android:id="@+id/View01"10 android:layout_width="wrap_content"11 android:layout_height="wrap_content"12 android:width="210px"13 android:height="50px"14 android:background="#ff0000"15 />16 <TextView android:id="@+id/View02"17 android:layout_width="wrap_content"18 android:layout_height="wrap_content"19 android:width="180px"20 android:height="50px"21 android:background="#dd0000" 22 />23 <TextView android:id="@+id/View03"24 android:layout_width="wrap_content"25 android:layout_height="wrap_content"26 android:width="150px"27 android:height="50px"28 android:background="#bb0000" 29 />30 <TextView android:id="@+id/View04"31 android:layout_width="wrap_content"32 android:layout_height="wrap_content"33 android:width="120px"34 android:height="50px"35 android:background="#990000" 36 />37 <TextView android:id="@+id/View05"38 android:layout_width="wrap_content"39 android:layout_height="wrap_content"40 android:width="90px"41 android:height="50px"42 android:background="#770000" 43 />44 <TextView android:id="@+id/View06"45 android:layout_width="wrap_content"46 android:layout_height="wrap_content"47 android:width="60px"48 android:height="50px"49 android:background="#550000" 50 />51 <TextView android:id="@+id/View07"52 android:layout_width="wrap_content"53 android:layout_height="wrap_content"54 android:width="30px"55 android:height="50px"56 android:background="#330000" 57 /> 58 </FrameLayout>
在GrapHical Layout模式下的:
上面的介面布局定義使用了FrameLayout,並向改布局添加了7個高度相同但寬度逐漸減少的TextView。
我們既然做的是霓虹燈,那就不能少了顏色。在values檔案夾下面我們還定義了一個color.xml檔案用來存放霓虹燈的所需的顏色[如所示]
Values/color.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <resources> 3 <color name="color1">#330000</color> 4 <color name="color2">#550000</color> 5 <color name="color3">#770000</color> 6 <color name="color4">#990000</color> 7 <color name="color5">#bb0000</color> 8 <color name="color6">#dd0000</color> 9 <color name="color7">#ff0000</color>10 </resources>
下面我們來看看主程式,主程式使用了上面的FrameLayout布局管理器,只是程式啟動了一條線程來控制周期性的改變7個TextView背景顏色,從而達到霓虹燈的效果。
com.example.framelayouttest.MainActivity.java
1 package com.example.framelayouttest; 2 3 import java.util.Timer; 4 import java.util.TimerTask; 5 6 import android.support.v7.app.ActionBarActivity; 7 import android.support.v7.app.ActionBar; 8 import android.support.v4.app.Fragment; 9 import android.os.Bundle;10 import android.os.Handler;11 import android.os.Message;12 import android.view.LayoutInflater;13 import android.view.Menu;14 import android.view.MenuItem;15 import android.view.View;16 import android.view.ViewGroup;17 import android.widget.TextView;18 import android.os.Build;19 20 public class MainActivity extends ActionBarActivity {21 22 private int currentColor = 0;23 //定義一個顏色數組24 final int [] colors = new int[]{25 R.color.color7,26 R.color.color6,27 R.color.color5,28 R.color.color4,29 R.color.color3,30 R.color.color2,31 R.color.color1,32 };33 34 35 final int [] names = new int[]{36 R.id.View01,37 R.id.View02,38 R.id.View03,39 R.id.View04,40 R.id.View05,41 R.id.View06,42 R.id.View07,43 };44 45 TextView[] views = new TextView[7];46 @Override47 protected void onCreate(Bundle savedInstanceState) {48 super.onCreate(savedInstanceState);49 setContentView(R.layout.main);50 //首先拿到7個TextView51 for (int i = 0 ; i < 7 ; i++)52 {53 views[i] = (TextView)findViewById(names[i]);54 }55 //Handler為android系統的線程通訊工具,承擔著主線程與分線程,分線程之間的通訊功能56 final Handler handler = new Handler(){57 @Override58 public void handleMessage(Message msg) {59 //表明訊息來自本程式所發送;what表示什麼事,when表示什麼時候60 if (msg.what == 0x1122) {61 //依次改變7個TextView的背景色62 for (int i = 0; i < 7 - currentColor ; i++) {63 views[i].setBackgroundResource(colors[i+currentColor]);64 }65 for (int i = 7 - currentColor,j = 0 ; i < 7; i++,j++) {66 views[i].setBackgroundResource(colors[j]);67 }68 }69 70 super.handleMessage(msg);71 }72 };73 74 //定義一個線程周期性的改變currentColor變數值,第二個參數0表示無延遲,第三個參數表示延遲多久1000表示一秒75 new Timer().schedule(new TimerTask() {76 77 @Override78 public void run() {79 currentColor ++;80 if (currentColor >=6) {81 currentColor=0;82 }83 //發送一條訊息通知系統改變7個TextView組件的背景色84 Message m = new Message();85 //給該訊息定義一個標識86 m.what = 0x1122;87 handler.sendMessage(m); 88 }89 }, 0, 100);;90 91 92 }93 94 }
上面程式定義了一個每0.1秒執行一次任務線程,該任務改變了currentColor的值然後想handler發送了一條訊息通知他更新7個textView的背景色。
才接觸Android的人也許會想我一樣會有點疑問:為什麼不直接在run裡面直接更新TextView的背景色。
我查了一下才知道Android的view和UI組件不是安全執行緒的,所以Android不允許開發人員啟動線程訪問使用者介面的UI組件。所以程式額外定義了一個Handler來處理TextView背景色的更新。