帧布局

     帧布局由FrameLayout所代表,FrameLayout直接继承了ViewGroup组件。

     帧布局容器为每个加入其中的组件创建一个空白区域(称为一个帧),每个子组件占据一帧,这些帧都会根据gravity属性执行自动对齐。帧布局的效果是把组件一个一个地叠加在一起。

     表2.7显示了FrameLayout常用的XML属性及相关方法说明。

           表2.7 FrameLayout的常用XML属性及相关方法

XML属性 相关方法      说  明         
android:foreground setForeground(Drawable) 设置该帧布局容器的前景图像
android:foregroundGravity setForegroundGravty(int) 定义绘制前景图像的gravity属性

       FrameLayout包含的子元素也受FrameLayout.LayoutParams控制,因此它所包含的子元素也可指定android:layout_gravity属性,该属性控制该子元素在FrameLayout中的对齐方式。

      下面示范了帧布局的用法,可以看到6个TextView叠加在一起,上面的TextView遮住下面的TextView。下面是使用帧布局的页面定义代码。

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:layout_gravity="center"
   >
   <!--依次定义6个TextView,先定义的TextView位于底层
   后定义的TextView位于上层  -->
  <!--android:gravity:属性是对该View中内容的限定,android:layout_gravity: 是用来设置View相对与父View的位置  -->
<TextView android:id="@+id/view01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:width="320dp" android:height="320dp" android:background="#f00" /> <TextView android:id="@+id/view02" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:width="280dp" android:height="280dp" android:background="#0f0" /> <TextView android:id="@+id/view03" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:width="240dp" android:height="240dp" android:background="#00f" /> <TextView android:id="@+id/view04" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:width="200dp" android:height="200dp" android:background="#ff0" /> <TextView android:id="@+id/view05" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:width="160dp" android:height="160dp" android:background="#f0f" /> <TextView android:id="@+id/view06" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:width="120dp" android:height="120dp" android:background="#0ff" />" </FrameLayout>

 上面的界面布局定义使用FrameLayout布局,并向该布局容器中添加了7个TextView,这7个TextView的高度完全相同,而宽度则逐渐减少——这样可以保证最新添加的TextView不会被完全遮挡;而且我们设置了7个TextView的背景色渐变。

  实例:霓虹灯效果

  如果考虑轮换改变上面的帧布局中6个TextView的背景色,就会看到上面的颜色渐变条不断地变换,就向大街上的霓虹灯一样。下面的程序还是使用上面的FrameLayout布局管理器,只是程序启动了一条线程来控制周期性地改变这6个TextView的背景色。下面是该主程序的代码。

package org.crazyit.helloworld;

import java.util.*;
import android.os.*;
import android.app.Activity;
import android.view.Menu;
import android.widget.*;

public class FrameLayout extends Activity {
    
    private int currentColor=0;
    //定义一个颜色数组
    final int[] colors=new int[]{R.color.red,R.color.blue,R.color.beige,R.color.black,
            R.color.brown,R.color.coral};
    final int[] names=new int[]{R.id.view01,R.id.view02,R.id.view03,R.id.view04,
            R.id.view05,R.id.view06};
    
    TextView[] views=new TextView[names.length];
    
    Handler handler=new Handler(){
        
        @Override
        public void handleMessage(Message msg)
        {
            //表明消息来自本本程序所发出
            if(msg.what==0x123)
            {
                for(int i=0;i<names.length;i++)
                {
                    views[i].setBackgroundResource(colors[(i+currentColor)%names.length]);
                }
                currentColor++;
            }
            super.handleMessage(msg);
        }
    };
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.frame_layout);
        for(int i=0;i<names.length;i++)
        {
            views[i]=(TextView)findViewById(names[i]);
        }
        //定义一个线程周期性的改变currentColor变量值
        new Timer().schedule(new TimerTask(){
            @Override
            public void run() {
                // TODO Auto-generated method stub
                //发送一条空消息通知系统改变6个TextView组件的背景色
                handler.sendEmptyMessage(0x123);
            }
        }, 0,200);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.frame_layout, menu);
        return true;
    }

}

    上面的程序中粗体字代码定义了一个米0.2秒执行一次的任务,该任务仅仅向Handler发送一条消息,通知它更新6个TextView的背景色。

    运行Activity可以看到如图2.12所示的效果。

  

图2.12帧布局

     上面的程序中粗体字代码定义了一个没0.2秒执行一次的任务,该任务仅仅向Handler发送一条消息,通知它更新6个TextView的背景色。

     到目前为止有一个疑问:为何不直接在run()方法里直接更新6个TextView的背景色呢?这是因为Android的View和UI组件不是线程安全的,所以Android不允许开发者启动线程访问用户界面的UI组件。所以程序中额外定义了一个Handler来处理TextView背景色的更新。

 

posted @ 2013-09-26 11:36  TealerProg  Views(1793)  Comments(0Edit  收藏  举报