4.霓虹灯效果

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

效果图:

MainActivity.java

 1 package com.example.aimee.tablelayouttest;
 2 
 3 import android.os.Handler;
 4 import android.os.Message;
 5 import android.support.v7.app.AppCompatActivity;
 6 import android.os.Bundle;
 7 import android.widget.TextView;
 8 
 9 import java.util.Timer;
10 import java.util.TimerTask;
11 
12 public class MainActivity extends AppCompatActivity {
13 
14     private int currentColor = 0;
15     //定义一个颜色数组
16     final int[] colors = new int[]{
17             R.color.color1,
18             R.color.color2,
19             R.color.color3,
20             R.color.color4,
21             R.color.color5,
22             R.color.color6
23     };
24 
25     final int[] names = new int[]{
26             R.id.view01,
27             R.id.view02,
28             R.id.view03,
29             R.id.view04,
30             R.id.view05,
31             R.id.view06
32     };
33 
34     TextView[] views = new TextView[names.length];
35     Handler handler = new Handler(){
36         @Override
37         public void handleMessage(Message msg) {
38             //表明消息来自本程序所发送的
39             if (msg.what == 0x123){
40                 for (int i=0;i<names.length;i++){
41                     views[i].setBackgroundResource(colors[(i+currentColor)%names.length]);
42                 }
43                 currentColor++;
44             }
45             super.handleMessage(msg);
46         }
47     };
48 
49     @Override
50     protected void onCreate(Bundle savedInstanceState) {
51         super.onCreate(savedInstanceState);
52         setContentView(R.layout.layout);
53         for (int i=0;i<names.length;i++){
54             views[i] = (TextView)findViewById(names[i]);
55         }
56         //定义一个线程周期性地改变currentColor变量值
57         new Timer().schedule(new TimerTask() {
58             @Override
59             public void run() {
60                 //发送一条空消息通知系统改变6个TextView组件的背景色
61                 handler.sendEmptyMessage(0x123);
62             }
63         },0,200);
64     }
65 }

 

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

可能会有人问:为何不直接在run()方法里直接更新6个TextView的背景色呢?

这是因为Android的View和UI组件不是线程安全的,所以Android不允许开发者启动线程访问用户界面的UI组件。因此,程序中额外定义了一个Handler来处理TextView背景色的更新。

简单来说,上面的程序通过任务调度控制了每间隔0.2秒轮换更新一次6个TextView的背景色,这样看上去就像大街上的霓虹灯了。

 

相对布局

相对布局由RelativeLayout所代表,相对布局容器内子组件的位置总是相对兄弟组件、父容器来决定的,因此这种布局方式被称为相对布局。

如果A组件的位置是由B组件的位置来决定的,Android要求先定义B组件,再定义A组件。

RelativeLayout可支持两个XML属性。

android:gravity——setGravity(int)

设置该布局容器内各子组件的对齐方式

android:ignireGravity——setIgnoreGravity(int)

设置哪个组件不受gravity属性的影响

为了控制该布局容器中各子组件的布局分布,RelativeLayout提供了一个内部类:RelativeLayout.LayoutParams,该类提供了大量的XML属性来控制RelativeLayout布局容器中子组件的布局分布。

RelativeLayout.LayoutParams里只能设为true,false的XML属性如下:

android:layout_centerhorizontal

控制该子组件是否位于布局容器的水平居中

android:layout_centervertical

控制该子组件是否位于布局容器的垂直居中

android:layout_centerInParent

控制该子组件是否位于布局容器的中央位置

android:layout_alignParentBottom

控制该子组件是否与布局容器低端对齐

android:layout_alignParentLeft

控制该子组件是否与布局容器左边对齐

android:layout_alignParentRight

控制该子组件是否与布局容器右边对齐

android:layout_alignParentTop

控制该子组件是否与布局容器顶端对齐

RelativeLayout.LayoutParams里属性值为其他UI组件ID的XML属性如下:

android:layout_toRightOf

控制该子组件位于给出ID组件的右侧

android:layout_toLeftOf

控制该子组件位于给出ID组件的左侧

android:layout_above

控制该子组件位于给出ID组件的上方

android:layout_below

控制该子组件位于给出ID组件的下方

android:layout_alignTop

控制该子组件与给出ID组件的上边界对齐

android:layout_alignBottom

控制该子组件与给出ID组件的下边界对齐

android:layout_alignLeft

控制该子组件与给出ID组件的左边界对齐

android:layout_alignRight

控制该子组件与给出ID组件的右边界对齐

除此之外,RelativeLayout.LayoutParams还继承了android.view.ViewGroup.MarginLayout Params,因此RelativeLayout布局容器中每个子组件也可指定android.view.ViewGroup.MarginLayout Params所支持的各XML属性

posted @ 2019-01-07 16:52  o云淡风轻o  阅读(285)  评论(0编辑  收藏  举报