Android模块化开发项目式教程(Android Studio)
上QQ阅读APP看书,第一时间看更新

项目2-3 用户注册界面设计

学习目标

■ 掌握RadioButton组件的使用方法,了解RadioButton组件事件监听处理机制。

■ 掌握Spinner组件的使用方法,了解Adapter适配器的用法。

■ 学会使用Spinner组件和Adapter适配器进行下拉列表设计。

■ 掌握Android表格布局技术。

■ 学会运用Android表格布局设计用户注册界面。

项目描述

运用Android表格布局技术,设计一个用户注册界面,要求在注册界面上运用RadioButton和Spinner组件。

知识储备

2.3.1 RadioButton组件

在Android中,RadioButton被称为单选按钮,功能与CheckBox正好相反,它用于在一组选项中进行单项选择,因此,RadioButton经常与表示一组选项的 RadioGroup单选按钮组一起使用。在一个RadioGroup单选按钮组中只可以选中一个RadioButton单选按钮,当选择了一个RadioButton单选按钮时,会取消其他已经选中的RadioButton单选按钮的选中状态。

1.RadioButton在XML文件中的基本语法

格式如下:

<RadioGroup

  属性列表

>

  <RadioButton

    属性列表 />

  <RadioButton

    属性列表 />

  ……

</RadioGroup>

例如,在XML文件中设计选择性别的方法,就是用一个RadioGroup单选按钮组。在该单选按钮组中设置两个RadioButton单选按钮,分别用于表示男和女选项。另外,用一个TextView组件来显示文字“性别”。用XML设计性别单选选项的代码如下:

<TextView

   android:layout_width="wrap_content"

   android:layout_height="wrap_content"

   android:text="性别"

   android:textSize="20sp"

   android:id="@+id/tv1"/>

<RadioGroup

   android:layout_width="wrap_content"

   android:layout_height="wrap_content"

   android:orientation="horizontal"

   android:id="@+id/sex">

   <RadioButton

     android:layout_width="wrap_content"

     android:layout_height="wrap_content"

     android:text="男"

     android:checked="true"

     android:id="@+id/rb1"/>

   <RadioButton

     android:layout_width="wrap_content"

     android:layout_height="wrap_content"

     android:text="女"

     android:checked="false"

     android:id="@+id/rb2"/>

</RadioGroup>

注意

RadioGroup、RadioButton组件添加在LinearLayout标签中。

2.RadioButton选中或未选中状态的设置方法

RadioButton组件选中或未选中状态的设置方法与CheckBox组件相似,可在XML文件中通过android:checked设置,也可在Java程序代码中通过setChecked(boolean)设置,并可通过 isChecked()方法来判断组件状态是否被选中,或者通过用户触摸改变选中状态。当RadioButton 组件状态发生改变时,将会触发 OnCheckedChange 响应事件,因此,可通过setOnCheckedChangeListener方法设置事件监听器,以实现对RadioButton状态变化的监控,并根据程序设计的不同要求重写OnCheckedChange响应事件中的代码。或者在XML中为每个RadioButton设置一个onClick()函数,然后在Activity的成员函数中实现。

例如,对选择性别的单选项设置事件监听器的代码如下:

public class MainActivity extends AppCompatActivity {

   //定义2个单选项变量

   private RadioButton radiobutton1;

   private RadioButton radiobutton2;

   @Override

   protected void onCreate(Bundle savedInstanceState) {

      super.onCreate(savedInstanceState);

      setContentView(R.layout.activity_main);

    / * 取得每个RadioButton1对象 */

      radiobutton1 = (RadioButton) findViewById(R.id.rb1);

      radiobutton2 = (RadioButton) findViewById(R.id.rb2);

      //对radiobutton1选项设置事件监听

      radiobutton1.setOnCheckedChangeListener(new CompoundButton.

      OnCheckedChangeListener()

      {

      @Override

      public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

       if(radiobutton1.isChecked())

       {

          Toast.makeText(MainActivity.this,"您选择了:" + radiobutton1.

          getText(),Toast.LENGTH_SHORT).show();

       }

      }

     });

      // radiobutton2选项设置事件监听方法同radiobutton1相似

      // 在此省略

   }

}

2.3.2 Spinner组件

Spinner 组件是通过下拉列表让用户选择一个选项的组件。一个 Spinner 对象包含多个子项,每个子项只有两种状态——选中或未选中。当用户单击倒三角按钮时,会弹出一个下拉列表,用户可通过单击其中某一个选项进行选择,如图2-10所示。

Spinner组件是AdapterView的子类,AdapterView是一种比较特殊的组件,AdapterView所派生出来的类都有一个共同点,即组件如果要显示数据必须要用到Adapter适配器,所谓适配器可以看成是一个桥梁,它连接着数据与组件,告诉组件如何显示这些数据,如图2-11所示。

图2-10 Spinner示意图

图2-11 适配器作用

1.Spinner在XML文件中的基本语法

格式如下:

<Spinner

  属性列表

/>

由于Spinner组件是AdapterView的子类,AdapterView是View类的子类,所以Spinner组件继承了许多View类的属性,但Spinner组件还有一些特有的XML属性,如以下几种。

① android:spinnerMode属性用于改变Spinner组件下拉列表框的样式,可以是弹出列表(dialog),也可是下拉列表(dropdown),默认是下拉列表。

② android:prompt属性用于设置当单击Spinner组件时显示下拉列表的标题,仅在dialog模式下有效,可以将其设定为一个类似于“@string/name”的字符串资源。

③ android:entries属性是在strings.xml文件中设定的一个数组资源,通过该属性将其设定为一个类似于“@string/array_name”的数组资源,Android将根据该数组资源来生成Spinner组件列表项。

2.Spinner组件重要方法

通过修改 XML 属性能很快设定组件的样式,但有时需要通过调用组件的方法来动态地修改组件属性,下面介绍Spinner组件的重要方法。

① Spinner类的方法:public void setAdapter(SpinnerAdapter adapter),该方法的参数是Adapter适配器,它的功能是设定组件所使用的适配器。

说明

Adapter适配器是一种连接数据与组件的桥梁,通过Adapter可以告诉组件要显示哪些数据,如何显示这些数据,并根据不同数据和组件的需要使用不同的 Adapter 适配器,常用的适配器有ArrayAdapter、SimpleAdapter、SimpleCursorAdapter 和 BaseAdapter。有关的适配器将在后面的学习中介绍。

如果连接的数据是数组类型,则需要使用 ArrayAdapter(数组适配器)。而该方法的参数是SpinnerAdapter,ArrayAdapter是SpinnerAdapter的间接子类,所以,该方法的参数也可以是ArrayAdapter。ArrayAdapter<T>是一种模板类型,尖括号中的T代表数组元素的数据类型,如连接整型数组的适配器应该是 ArrayAdapter<Integer>,而连接字符串数组的配器应该是ArrayAdapter<String>。

② ArrayAdapter 的构造方法:ArrayAdapter(Context context,int textViewResourceId, T[] object),它的参数context为当前Activity的环境,下拉列表中的每一个选项将会作为TextView显示,textViewResourceId就是TextView组件的ID,object为适配器需要连接的数组数据。

③ ArrayAdapter类的方法:public void setDropDownViewResourcer(int resource),它的功能是设置下拉菜单的显示样式,参数 resource为下拉菜单显示样式 XML资源文件,可以利用 Android 系统自带的样式,如默认值 android.R.layout.simple_spinner_item 和android.R.layout.simple_spinner_dropdown_item。

3.Spinner组件的使用

(1)通过数组资源文件,静态展示Spinner选项。

示例:用Spinner组件显示所要选择的职业分别为教师、工人、农民、作家、演员等。首先在 strings.xml 资源文件中添加字符串数组名为“profession”,内容为教师、工人、农民、作家、演员等 item 选项,设置下拉列表标题的字符串资源(spin_prompt),代码如下:

<resources>

   <string name="spin_prompt">请选择职业</string>

   <string-array name="profession">

      <item> 教师 </item>

      <item> 工人 </item>

      <item> 农民 </item>

      <item> 作家 </item>

      <item> 演员 </item>

   </string-array>

</resources>

然后,在activity_main.xml布局文件中添加Spinner组件,设置Spinner组件的属性如下:

<Spinner

   android:layout_width="wrap_content"

   android:layout_height="wrap_content"

   android:id="@+id/spinner1"

   android:entries="@array/profession"

   android:spinnerMode="dialog"

   android:prompt = "@string/spin_prompt"

/>

注意

android:prompt必须要引用strings.xml中的资源ID,而不能在这里直接用文字。另外,android:prompt只有在dialog模式下才有效。

(2)通过Java代码方式,动态展示Spinner选项。

首先,在activity_main.xml布局文件中添加Spinner组件,设置Spinner组件属性的代码如下:

<Spinner

  android:layout_width="wrap_content"

  android:layout_height="wrap_content"

  android:id="@+id/spinner1"

/>

然后,修改MainActivity.java。首先创建存放Spinner选项的数组,然后,创建ArrayAdapter数组适配器,在ArrayAdapter构造时第1个参数为this,代表当前Activity的环境;第2个参数为android.R.layout.simple_spinner_item,注意该ID是以“android”开头,代表Android系统自带布局中的组件,本质上是Android系统自带的用于显示选项的TextView组件ID;第3个参数为profession,代表字符串数组。最后,通过setAdapter方法设定Spinner组件的数据源。其相关Java代码如下:

public class MainActivity extends AppCompatActivity {

   //定义一个用于存放Spinner选项的数组

   private static final String[] profession = {"教师" , "工人" , "农民" , "作家" ,"演员"};

   //定义Spinner变量

   private Spinner spinner;

   @Override

   protected void onCreate(Bundle savedInstanceState) {

      super.onCreate(savedInstanceState);

      setContentView(R.layout.activity_main);

      //从数组创建ArrayAdapter数组适配器

      ArrayAdapter<String> adapter = new ArrayAdapter<String>( this,android.R.lay

      out.simple_spinner_item,profession);

      //设置下拉菜单的显示样式

      adapter.setDropDownViewResource(android.R.layout.simple_spinner_item);

      //设置Spinner数据源

      spinner = (Spinner) findViewById(R.id.spinner1);

      spinner.setAdapter(adapter);

   }

}

利用这种方法不需要在strings.xml资源文件中定义任何资源。

4.Spinner组件监听器

Spinner组件最重要的监听器实际上就是用户选择了某个选项的监听器,设定该监听器的方法为Public void setOnItemSelectedListener(AdapterView.OnItemSelectedListener listener),其中, AdapterView.OnItemSelectedListener是选项监听器。它的功能是监听Spinner选项被选中的事件,该方法是Spinner组件从其父类AdapterView中继承得到的。示例如下:

spinner = (Spinner) findViewById(R.id.spinner1);

  spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {

     @Override

     public void onItemSelected(AdapterView<?>parent,View view,int position,long id) {       //将选项视图转换为TextView类型

         TextView txt = (TextView)view;

         //获取选中项的显示字符串

         String strName = txt.getText().toString();

    }

     @Override

     public void onNothingSelected(AdapterView<?> parent) {

      //没有任何选项被选中时处理代码

    }

  });

OnItemSelectedListener接口需要实现两个方法,一个是onItemSelected(选项被选中时触发),另一个是 onNothingSelected(没有任何选项被选中时触发),一般情况下是在onItemSelected添加处理代码,onItemSelected方法中的参数parent为单击的Spinner组件, view为单击的那一项的视图,position为单击的那一项的位置。

2.3.3 表格布局

表格布局与常见的表格类似,它是以行和列的形式管理组件。表格布局使用< TableLayout>为标记定义,在表格布局中,每行为一个TableRow对象,也可以为一个View对象。当为View对象时,该 View对象将独占一行,当为 TableRow对象时,可在 TableRow下添加子组件,默认情况下,每个子组件占据一列。

表格布局的行数由开发人员决定,有多少个TableRow对象(或View对象),就有多少行。而表格布局的列数等于含有最多子组件的行(TableRow)的列数。例如,有一表格布局是3行,第1行含2个子组件,第2行含3个子组件,第3行含4个子组件,那么该表格布局的列数为4。

在Android中,可以使用XML布局文件定义表格布局管理器,也可以使用Java来创建,但推荐使用XML布局文件定义表格布局管理器。在XML布局文件中,定义表格布局管理器的基本语法格式如下:

<TableLayout

   属性列表 >

   <TableRow>

      需要添加的UI组件

   </TableRow>

      多个<TableRow>

</TableLayout>

表格布局TableLayout类继承自LinearLayout类,它除了继承来自父类的属性和方法外,还包含表格布局所特有的属性和方法。表格布局的属性包括全局属性和单元格属性,其中全局属性也称为列属性,列属性及其对应方法如表2-13所示。

表2-13 TableLayout类列属性及其对应方法

示例:

android:stretchColumns="0",表示第0列可伸展。

android:shrinkColumns="1,2",表示第1、2列皆可收缩。

android:collapseColumns="*",表示隐藏所有行。

说明

列可以同时具备stretchColumns和shrinkColumns属性。

表格布局的单元格属性,有以下两个参数。

android:layout_column用于指定该单元格在第几列显示;

android:layout_span用于指定该单元格占据的列数(未指定时,为1)。

示例:

android:layout_column="1",表示该组件显示在第1列。

android:layout_span="2",表示该组件占据2列。

说明

一个组件也可以同时具备全局属性和单元格属性。

项目实施

1.项目分析

运用Android表格布局技术,设计一个用户注册界面,效果如图2-12所示。

图2-12 用户注册界面

用户注册界面设计特点:

① 整个界面可看成由5行组成。

② 第1~3行出现图片,跨越3行文字。

③ 第4行由4列组成。

④ 第5行由2列组成。

分析结果:

① 整个界面看成是由两个表格布局组成的。

② 第1个表格布局由图片、用户名、密码和确认密码组成。

③ 第2个表格布局由性别、职业、注册和重置组成。

④ UI 界面中有单选按钮、下拉列表、ImageView、TextView、EditText和Button等组件。

⑤ 采用线性布局和表格布局技术。

2.项目实现

(1)打开用户登录项目。

启动Android Studio,在Android Studio起始页选择【Open an existing Android Studio project】,或在Android Studio主页菜单栏上选择【File】→【Open】,选择打开用户登录项目。

(2)在用户登录项目中创建用户注册界面。

操作方法:右击图2-13所示的app下【java】项,选择快捷菜单【New】→【Activity】→【Empty Activity】。然后,修改Activity Name名称为RegisterActivity,Layout Name的名称为activity_register。单击【Finish】按钮。

图2-13 右击【java项】

(3)设计布局文件。

在res/layout文件夹中,打开布局的activity_register.xml文件,使用线性布局和表格布局技术进行设计,首先将默认的相对布局修改成线性布局,并设置 android:orientation="vertical",然后嵌套一个线性布局,在此线性布局中放置一个图片组件和一个表格布局组件,并在此线性布局下方放置一个表格布局组件。

操作方法:展开【res】→【layout】文件夹,双击【activity_register.xml】文件,打开右侧布局文件text编辑窗口,在编辑窗口中输入activity_register.xml文件代码,如下:

<?xml version="1.0" encoding="utf-8"?>

<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:layout_margin="45dp"

  android:orientation="vertical"

  tools:context="com.zzhn.zheng.test.ZhuCeActivity">

  <LinearLayout

    android:layout_width="match_parent"

    android:layout_height="wrap_content"

    android:orientation="horizontal">

    <ImageView

     android:layout_width="80dp"

     android:layout_height="100dp"

     android:src="@drawable/copyright"/>

     <TableLayout

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:shrinkColumns="*">

       <TableRow>

        <TextView

           android:layout_width="wrap_content"

           android:layout_height="wrap_content"

           android:text="用户名:"

           android:textSize="20sp"/>

        <EditText

           android:layout_height="wrap_content"

           android:layout_width="wrap_content"

           android:hint="用户名"

           android:id="@+id/username"/>

       </TableRow>

       <TableRow>

         <TextView

           android:layout_width="wrap_content"

           android:layout_height="wrap_content"

           android:text="密 码:"

           android:textSize="20sp"/>

         <EditText

           android:layout_height="wrap_content"

           android:layout_width="wrap_content"

           android:hint="密 码"

           android:inputType="numberPassword"

           android:id="@+id/userpwd"/>

       </TableRow>

       <TableRow>

         <TextView

           android:layout_width="wrap_content"

           android:layout_height="wrap_content"

           android:text="确认密码:"

           android:textSize="20sp"/>

         <EditText

           android:layout_height="wrap_content"

           android:layout_width="wrap_content"

           android:hint="确认密码"

           android:inputType="numberPassword"

           android:id="@+id/conpwd"/>

       </TableRow>

     </TableLayout>

  </LinearLayout>

  <TableLayout

    android:layout_width="match_parent"

    android:layout_height="wrap_content" >

     <TableRow>

      <TextView

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="性别"

        android:textSize="20sp"/>

      <RadioGroup

        android:id="@+id/rg1"

        android:orientation="horizontal"

        android:gravity="left"

        android:layout_width="match_parent"

        android:layout_height="wrap_content">

        <RadioButton

          android:layout_width="wrap_content"

          android:layout_height="wrap_content"

          android:textColor="#3F51B5"

          android:checked="true"

          android:text="男"

          android:id="@+id/rb_1"/>

        <RadioButton

          android:layout_width="wrap_content"

          android:layout_height="wrap_content"

          android:textColor="#3F51B5"

          android:checked="false"

          android:text="女"

          android:id="@+id/rb_2"/>

      </RadioGroup>

        <TextView

          android:layout_width="wrap_content"

          android:layout_height="wrap_content"

          android:paddingLeft="20dp"

          android:text="职业"

          android:textSize="20sp"/>

       <Spinner

          android:layout_width="match_parent"

          android:layout_height="wrap_content"

          android:id="@+id/spinner1"

          android:entries="@array/profession"/>

     </TableRow>

     <TableRow>

       <Button

         android:layout_width="wrap_content"

         android:layout_height="wrap_content"

         android:layout_span="2"

         android:id="@+id/bt1"

         android:text="注册"/>

       <Button

         android:layout_width="wrap_content"

         android:layout_height="wrap_content"

         android:layout_span="2"

         android:id="@+id/bt2"

         android:text="重置"/>

     </TableRow>

  </TableLayout>

</LinearLayout>

(4)调试运行。

① 修改清单文件AndroidManifest.xml,让程序从ZhuCeActivity启动。

② 单击工具栏上的AVD Manager图标,打开虚拟设备对话框,在虚拟设备对话框中单击启动虚拟设备的命令按钮,打开Android Studio模拟器。

③ 单击工具栏上的“三角形”运行按钮,运行本项目。

项目总结

通过本项目的学习,读者应学会采用线性布局和表格布局技术设计用户注册界面的方法。

① 用户注册界面是由TextView、EditText、ImageView、RadioButton、Spinner和Button等组件组成的,读者应了解这些组件的常用属性。

② 采用表格布局技术,进行用户注册界面设计。读者应掌握表格布局中全局属性及单元格属性的运用。

项目训练——用表格布局设计计算器界面

用表格布局设计计算器界面,效果如图2-14所示。

图2-14 计算器界面效果

练习题

2-3-1 修改用户注册界面的XML文件,要求将界面上显示的文字放置于strings.xml文件中。

2-3-2 说明表格布局设计的特点。

2-3-3 说明Spinner设计方法和适配器的作用。常用适配器有哪些?

2-3-4 RadioButton是如何实现单选功能的?如何监控RadioButton组件选中状态的改变?