首页 > 代码库 > Android 自学之帧布局 FrameLayout

Android 自学之帧布局 FrameLayout

帧布局(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     @Override
47     protected void onCreate(Bundle savedInstanceState) {
48         super.onCreate(savedInstanceState);
49         setContentView(R.layout.main);
50         //首先拿到7个TextView
51         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             @Override
58             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             @Override
78             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背景色的更新。