除了最经常用到的TextView视图之外,还有其他一些您将频繁使用到的基础视图:
● Button—表示一个按钮的小部件。
● ImageButton—与Button视图类似,不过它还显示一个图像。
● EditText—TextView视图的子类,还允许用户编辑其文本内容。
● CheckBox—具有两个状态的特殊按钮类型:选中或未选中。
● RadioGroup和RadioButton—RadioButton有两个状态:选中或未选中。RadioGroup用来把一个或多个RadioButton视图组合在一起,从而在该RadioGroup中只允许一个RadioButton被选中。
● ToggleButton—用一个灯光指示器来显示选中/未选中状态
下面的“试一试”揭示了这些视图工作原理的细节。
试一试 使用基本视图
BasicViews1.zip代码文件可以在Wrox.com上下载
(1) 使用Eclipse创建一个Android项目,命名为BasicView1.
(2) 在位于res/layout文件夹下的main.xml文件中添加下列粗体显示的元素:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button android:id="@+id/btnSave"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="save" />
<Button android:id="@+id/btnOpen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Open" />
<ImageButton android:id="@+id/btnImg1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher" />
<EditText android:id="@+id/txtName"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<CheckBox android:id="@+id/chkAutosave"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Autosave" />
<CheckBox android:id="@+id/star"
style="?android:attr/starStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<RadioGroup android:id="@+id/rdbGp1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<RadioButton android:id="@+id/rdb1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Option 1" />
<RadioButton android:id="@+id/rdb2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Option 2" />
</RadioGroup>
<ToggleButton android:id="@+id/toggle1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
(3) 要观察视图的效果,可在Eclipse中选择项目名称并按F11键进行调试。图4-1展示了在Android模拟器中显示的不同视图。
(4) 单击不同的视图并注意它们在外观和感觉上的变化。图4-2展示了视图的以下改变:
● 第1个CheckBox视图(Autosave)被选中。
● 第2个CheckBox视图(星形)被选中。
● 第2个RadioButton(Option 2)被选中。
● ToggleButton被打开。
示例说明
到目前为止,所有的视图都是相对简单的—使用<LinearLayout>元素将它们一一列出,因此当在活动中显示时,它们堆叠在彼此之上。
对于第1个Button,layout_width属性被设置为fill_parent,因此其宽度将占据整个屏幕的宽度:
<Button android:id="@+id/btnSave"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="save" />
对于第2个Button,layout_width属性被设置为wrap_content,因此其宽度将是其所包含内容的宽度—具体来说,就是显示的文本(也就是“Open”)的宽度:
<Button android:id="@+id/btnOpen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Open" />
ImageButton显示了一个带有图像的按钮。图像通过src属性设置。本例中,使用曾用作应用程序图标的图像:
<ImageButton android:id="@+id/btnImg1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher" />
EditText视图显示了一个矩形区域,用户可以向其中输入一些文本。layout_height属性被设置为wrap_content,这样,如果用户输入一个长的文本串,EditText的高度将随着内容自动调整(如图4-3所示)。
<EditText android:id="@+id/txtName"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
CheckBox显示了一个用户可以通过轻点鼠标进行选中或取消选中的复选框:
<CheckBox android:id="@+id/chkAutosave"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Autosave" />
如果您不喜欢CheckBox的默认外观,可以对其应用一个样式属性,使其显示为其他图像,如星形:
<CheckBox android:id="@+id/star"
style="?android:attr/starStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
style属性的值的格式如下所示:
?[package:][type:]name
RadioGroup包含了两个RadioButton。这一点很重要,因为单选按钮通常用来表示多个选项以便用户选择。当选择了RadioGroup中的一个RadioButton时,其他所有RadioButton就自动取消选择:
<RadioGroup android:id="@+id/rdbGp1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<RadioButton android:id="@+id/rdb1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Option 1" />
<RadioButton android:id="@+id/rdb2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Option 2" />
</RadioGroup>
注意,RadioButton是垂直排列的,一个位于另一个之上。如果想要水平排列,需要把orientation属性改为horizontal。还需要确保RadioButton的layout_width属性被设置为wrap_content:
<RadioGroup android:id="@+id/rdbGp1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<RadioButton android:id="@+id/rdb1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Option 1" />
<RadioButton android:id="@+id/rdb2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Option 2" />
</RadioGroup>
图4-4显示了水平排列的RadioButton。
ToggleButton显示了一个矩形按钮,用户可以通过单击它来实现开和关的切换:
<ToggleButton android:id="@+id/toggle1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
这个例子中,始终保持一致的一件事情是每个视图都有一个设置为特定值的id属性,如Button视图中所示:
<Button android:id="@+id/btnSave"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/save" />
id属性是视图的标识符,因此可以在以后使用View.findViewById()或Activity.findViewById()方法来检索它。
刚才看到的各种视图是在模拟Android 4.0智能手机的Android模拟器上进行测试的。当运行在较早版本的Android智能手机上时,它们会是什么样子?运行在Android平板电脑上时,又会是什么样子?
图4-5显示了将AndroidManifest.xml文件的android:minSdkVersion属性改为10,并在运行Android 2.3.6的Google Nexus S上运行时,活动的外观:
<uses-sdk android:minSdkVersion="10" />
图4-6显示了将AndroidManifest.xml文件中的android:minSdkVersion属性改为13,并在运行Android 3.2.1的Asus Eee Pad Transformer上运行时,活动的外观:
如果将android:minSdkVersion属性设为8或更小,然后在运行Android 3.2.1的Asus Eee Pad Transformer上运行,会看到额外的一个按钮,如图4-7所示。
点击该按钮会出现两个选项,它们分别可以将活动拉伸到填充整个屏幕(默认选项),或将活动缩放到填充整个屏幕,如图4-8所示。
简言之,将最低SDK版本设为8或更低的应用程序可以在最初设计的屏幕尺寸上显示,也可以自动拉伸以填充屏幕(默认行为)。
现在,您已经了解了一个活动的多种视图的外观,下面的“试一试”将教您如何以编程方式控制它们。
试一试 处理视图事件
(1) 使用前面的“试一试”所创建的BasicViews1项目,修改BasicViews1Activity.java文件,添加下列粗体显示的语句:
(2) 按F11键在Android模拟器中调试项目。
(3) 单击不同的视图,观察在Toast窗口中显示的消息。
示例说明
为了处理每一个视图所触发的事件,首先需要以编程方式定位在onCreate()事件中所创建的视图。做法是使用Acitivity基类的 findViewById()方法,传入该视图的ID。
//---Button view---
Button btnOpen = (Button) findViewById(R.id.btnOpen);
setOnClickListener()方法注册了一个在视图被单击时调用的回调函数:
btnOpen.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
DisplayToast("You have clicked the Open button");
}
});
当单击视图时,将调用onClick()方法。
对于CheckBox,为了确定其状态,必须把onClick()方法的参数类型转换成一个CheckBox,然后检查它的isChecked()方法来确定其是否被选中:
CheckBox checkBox = (CheckBox) findViewById(R.id.chkAutosave);
checkBox.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v) {
if (((CheckBox)v).isChecked())
DisplayToast("CheckBox is checked");
else
DisplayToast("CheckBox is unchecked");
}
});
对于RadioButton,需要使用RadioGroup的setOnCheckedChangeListener()方法注册一个回调函数,以便在该组中被选中的RadioButton发生变化时调用:
//---RadioButton---
RadioGroup radioGroup = (RadioGroup) findViewById(R.id.rdbGp1);
radioGroup.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
public void onCheckedChanged(RadioGroup group, int checkedId) {
RadioButton rb1 = (RadioButton) findViewById(R.id.rdb1);
if (rb1.isChecked()) {
DisplayToast("Option 1 checked!");
} else {
DisplayToast("Option 2 checked!");
}
}
});
当选中一个RadioButton时,将触发onCheckedChanged()方法。在这一过程中,找到那些单个的RadioButton,然后调用它们的isChecked()方法来确定是哪个RadioButton被选中。或者,onCheckedChanged()方法包含第2个参数,其中包含被选定RadioButton的唯一标识符。
ToggleButton的工作方式与CheckBox类似。
到目前为止,为了处理视图上的事件,首先需要获得视图的一个引用,然后需要注册一个回调函数来处理事件。还有另外一种处理视图事件的方法。以Button为例,可以向其添加一个名为onClick的属性:
<Button android:id="@+id/btnSave"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/save"
android:onClick="btnSaved_clicked"/>
onClick属性指定了按钮的单击事件。该属性的值就是事件处理程序的名称。因此,为处理按钮的单击事件,只需要创建一个名为btnSaved_clicked的方法,如下面的示例所示(注意该方法必须有一个View类型的参数):
public class BasicViews1Activity extends Activity {
public void btnSaved_clicked (View view) {
DisplayToast("You have clicked the Save button1");
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//...
}
private void DisplayToast(String msg)
{
Toast.makeText(getBaseContext(), msg,
Toast.LENGTH_SHORT).show();
}
}
如果与前面使用的方法进行比较,会发现这种方法更加简单。使用哪种方法取决于您自己,但本书中主要使用后面这种方法。