



前面已经介绍了Android UI组件的基本知识,那么再来了解如何使用Android SDK中定义的UI组件进行界面编程。
前面介绍的View组件是Java的类,Android除了提供使用定义Java对象的形式来定义View组件,还可以使用XML布局文件的方式来定义View组件,并且Android也推荐使用XML布局文件。但是无论是使用Java对象,还是使用XML布局文件,控制Android UI组件的行为本质上是一致的,大部分时候UI组件标签的XML属性,在Java类中还存在对应的getter、setter方法。,在工作中,Android推荐使用XML布局文件。
View的常用XML属性及方法说明:
| XML属性 | 相关方法 | 说明 |
| android:alpha | setAlpha(float) | 设置该组件的透明度 |
| android:background | setBackgroundResource(int) | 设置该组件的背景 |
| android:clickable | setClickable(boolean) | 设置该组件是否可以响应点击事件 |
| android:longClickable | setLongClickable(boolean) | 设置该组件是否可以响应长按事件 |
| android:onClick | 为该组件的单击事件绑定监听器 | |
| android:focusable | setFocusable(boolean) | 设置该书剑是否可以得到焦点 |
| android:id | setId(int) | 设置该组件的唯一标识 |
| android:keepScreenOn | setKeepScreenOn(boolean) | 设置该组件是否强制屏幕常亮 |
| android:layout_gravity | - | 设置该组件在容器内的权重 |
| android:layout_height |
setLayoutParames
(View.Group.LayoutParams) |
设置该组件在其父容器中的高度 |
| android:layout_width |
setLayoutParames
(View.Group.LayoutParams) |
设置该组件在其父容器中的宽度 |
| android:layout_margin | - | 设置该组件在其父容器中布局时的边距 |
| android:minHeight | - | 设置该组件的最小高度 |
| android:minWidth | - | 设置该组件的最小宽度 |
| android:padding | setPadding | 在组件的四边设置填充区域 |
| android:saveEnabled | setSaveEnabled(boolean) | 设置是否在冻结的时候保持组件的状态 |
| android:visibility | setVisibility(int) | 设置该组件是否可见 |
表3-1常用XML属性以及方法,可能说明里描述的不是很清晰,在后面介绍详细UI组件的时候,对应的属性也将详细介绍到,这里不再赘述。
定义UI组件后,必须使用Android四大组件之一的Activity对其进行承载,对于Activity的内容,将再后面的章节中讲解到。
Android推荐使用XML资源文件定义UI组件,这样暗合了MVC的原则。MVC全名是Model View Controller,是模型(model)-视图(View)-控制器(Controller)的缩写,它是一种软件设计模式,使用MVC的目的是将模型与视图的实现代码分离,从而使同一个程序可以使用不同的表现形式。Android推荐使用XML布局来定义UI组件的意义,不仅UI组件的结构清晰,简单明了,也把视图和逻辑进行了分离。
XML布局文件必须定义在res/layout目录下,并且文件名只能小写字母构成。当定义好一个XML布局文件之后,R.java会自动收录该布局资源,在Java代码中可以通过Activity.setContentView()方法,指定Activity显示的内容视图。setContentView()方法具有多个重载方法,这里给出使用XML布局文件的方法的完整签名:
public void setContentView(int layoutResID)
当XML布局文件中定义了多个UI组件的时候,可以使用UI组件的android:id属性为其制定资源ID,资源ID是这个XML布局文件中UI组件的唯一标识,当为UI组件定义了ID之后,R.java中会自动收录其ID。这样就可以在Activity中,通过Activity.findViewById()方法找到这个UI组件进行操作,下面是findViewById()方法的完整签名:
public View findViewById(int id)
可以看出,findViewById()方法返回的是所有UI组件的父类:View,要操作具体UI组件,还需要对其进行强制类型转换。一旦获取到UI组件的对象,那么接下来就可以通过Java代码来控制它了。
在使用XML布局资源文件定义UI组件的时候,有两点需要特别注意:
1. 在同一项目的多个XML布局资源文件中定义的UI组件,ID是允许重名的,但是在单个XML布局文件中,ID必须唯一。
2. 因为不同XML布局文件中UI组件ID可以重名,所以在Activity中,使用findViewById()方法查找XML布局文件中定义的UI组件时,必须先调用Activity.setContentView()方法进行指定Activity的内容视图。
示例:使用XML布局文件定义一个UI界面,并且对其进行简单的操作。
代码清单:\codes\03\3.2\XmlFileDefineLayout\res\layout\activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<!-- 定义一个按钮,并指定点击事件名为:btnClick -->
<Button
android:id="@+id/btn_click"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="btnClick"
android:text="Say hello" />
<!-- 定义一个文本显示控件,用于文本 -->
<TextView
android:id="@+id/tv_show"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
代码清单:\codes\03\3.2\XmlFileDefineLayout\src\com\bookdemo\xmlfiledefinelayout\MainActivity.java
public class MainActivity extends Activity {
private TextView tv_show;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 为Activity指定内容视图
setContentView(R.layout.activity_main);
// 找到文本显示控件
tv_show=(TextView) findViewById(R.id.tv_show);
}
/**
* 按钮控件响应的点击事件
* @param v 当前触发点击事件的View
*/
public void btnClick(View v){
tv_show.setText("Hello Android");
}
}
在模拟器上调试运行,效果如下:
虽然Android推荐使用XML布局文件来定义UI组件,但是如果需要,除了使用XML布局文件来定义UI组件,还可以使用Java代码来动态定义与控制UI组件。前面介绍到,UI组件在XML布局文件中以XML标签的形式定义,但是大部分标签在Android SDK中均有对应的类,使用Java代码动态定义UI组件即是操作这些类的行为。
定义好的布局对象还需要有Activity来承载显示,所以需要调用Activity.setContentView()方法来为Activity指定显示的布局对象,这里使用的是setContentView()另外一个重载方法,其完整签名如下:
public void setContentView(View view)
示例:通过一个简单的示例演示如何在运行时,完全依赖动态Java代码的形式,进行UI界面布局。
代码清单:\codes\03\3.2\JavaCodeDefineLayout\src\com\bookdemo\javacodedefinelayout\MainActivity.java
public class MainActivity extends Activity {
private LinearLayout layout;
private Button btnClick;
private TextView tvShow;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 不使用XML布局文件定义Activity的内容视图
// setContentView(R.layout.activity_main);
// 定义一个线性布局对象
layout=new LinearLayout(this);
// 指定线性布局方向为垂直
layout.setOrientation(LinearLayout.VERTICAL);
// 指定其为匹配父窗口
layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
// 定义一个按钮对象
btnClick=new Button(this);
btnClick.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
// 指定其显示文本
btnClick.setText("Say hello");
// 为按钮添加点击响应监听器
btnClick.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(tvShow!=null){
tvShow.setText("Hello Android");
}
}
});
// 定义一个文本展示控件
tvShow=new TextView(this);
tvShow.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
// 把定义的UI控件添加到布局对象中
layout.addView(btnClick);
layout.addView(tvShow);
// 指定Activity的内容视图为定义的线性布局对象
setContentView(layout);
}
}
在模拟器上运行会发现其效果与使用XML布局文件定义UI的示例一样,如下图: