第3章 多个用户界面的程序设计 ?3.1 页面切换与传递参数值 * 3.1.1 绑定机制组件 Intent是Android系统的一种运行时的绑定机制,在应用程序运行时连接两个不同组件。在Android 的应用程序中,不管是页面切换、传递数据,还是调用外部程序,都可能要用到Intent。Intent负责对应用中某次操作的动作、动作涉及的数据、附加数据进行描述。Android则根据Intent的描述,负责找到对应的组件,将 Intent传递给调用的组件,并完成组件的调用。因此,可以将Intent理解为不同组件之间通信的“媒介”,其专门提供组件互相调用的相关信息。 Intent的属性有动作(Action)、数据(Data)、分类(Category)、类型(Type)、组件(Component)以及扩展(Extra),其中最常用的是Action属性。 例如: Intent.ACTION_MAIN 表示标识Activity为一个程序的开始。 Intent.ACTION_GET_CONTENT 表示允许用户选择图片或录音等特殊种类的数据。 Intent.ACTION_SMS_SEND 表示发送邮件的动作。 Intent.ACTION_SMS_RECEIVED 表示接收邮件的动作。 Intent.ACTION_ANSWER 表示处理呼入的电话。 Intent.ACTION_CALL_BUTTON 表示按“拨号”键。 Intent.ACTION_CALL 表示呼叫指定的电话号码。 * 3.1.2 Activity页面切换 Activity跳转与传递参数值主要通过Intent类协助实现。在一个Activity页面中启动另一个Activity页面的运行,这是最简单的Activity页面切换方式。 页面切换的步骤如下: (1)首先创建一个Intent对象,其构造方法如下。 Intent intent = new Intent(当前Activity.this, 另一Activity.class); (2)调用Activity的startActivity(intent)方法,切换到另一个Activity页面。 【例3-1】 从一个Activity页面启动另一个Activity页面示例。 创建名称为ex3_1的新项目,包名为com.example.ex3_1。在本项目中要建立两个页面文件及两个控制文件,第1个页面的界面布局文件为activity_main.xml、控制文件为MainActivity.java,第2个页面的界面布局文件为activity_second.xml、控制文件为secondActivity.java。此外,还要修改配置文件AndroidManifest.xml。 (1)设计第1个页面。 ① 进入系统自动生成的应用程序框架,在页面的界面布局中,设置一个文本标签组件和一个按钮组件,建立组件约束如图3.1所示。 图3.1 第1个页面的界面布局及组件约束 ② 修改第1个页面的控制文件MainActivity.java,源代码如下: 1 package com.example.ex3_1; 2 import androidx.appcompat.app.AppCompatActivity; 3 import android.os.Bundle; 4 import android.widget.Button; 5 import android.content.Intent; 6 import android.view.View; 7 public class MainActivity extends AppCompatActivity 8 { 9 private Button okBtn; 10 Intent intent; 11 @Override 12 public void onCreate(Bundle savedInstanceState) 13 { 14 super.onCreate(savedInstanceState); 15 setContentView(R.layout.activity_main); 16 btn = (Button)findViewById(R.id.button); 17 btn.setOnClickListener(new mClick());; 18 } 19 class btnclock implements OnClickListener 20 { 21 public void onClick(View v) 22 { 23 intent = new Intent(MainActivity.this, secondActivity.class); 24 startActivity(intent); //启动新的Activity页面 25 } 26 } 27 } (2)设计第2个页面。 ① 右击项目管理器中的app/java/com.example.ex3_1选项,在弹出的快捷菜单中选择New(新建)→Activity→Empty Activity选项,如图3.2所示。 图3.2 新建第2个页面 在弹出的对话框中,输入第2个页面的Activity名称SecondActivity,其页面布局 Layout名称为activity_second,如图3.3所示。 图3.3 配置第2个页面 这时,系统自动生成第2个页面的界面布局文件activity_second.xml和控制文件secondActivity.java。 ② 在第2个页面的界面中,设置一个文本标签,将其text属性值设置为“这是第2个页面”。自动生成的第2个页面的控制程序secondActivity.java代码不需要任何修改,其代码如下。 1 ackage com.example.ex3_1; 2 import androidx.appcompat.app.AppCompatActivity; 3 import android.os.Bundle; 4 ublic class SecondActivity extends AppCompatActivity { 5 @Override 6 protected void onCreate(Bundle savedInstanceState) { 7 super.onCreate(savedInstanceState); 8 setContentView(R.layout.activity_second); 9 } 10 } (3)配置文件AndroidManifest.xml。 打开项目中的AndroidManifest.xml配置文件,可以看到增加了一行注册第2个Activity页面的代码,其程序代码如下。 1 <?xml version="1.0" encoding="utf-8"?> 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 3 package="com.example.ex3_1"> 4 <application 5 android:allowBackup="true" 6 android:icon="@mipmap/ic_launcher" 7 android:label="@string/app_name" 8 android:roundIcon="@mipmap/ic_launcher_round" 9 android:supportsRtl="true" 10 android:theme="@style/Theme.Ex3_1"> 11 <activity android:name=".SecondActivity"></activity> 12 <activity android:name=".MainActivity"> 13 <intent-filter> 14 <action android:name="android.intent.action.MAIN" /> 15 <category android:name="android.intent.category.LAUNCHER" /> 16 </intent-filter> 17 </activity> 18 </application> 19 </manifest> 程序运行结果如图3.4所示。 图3.4 从一个页面切换到另一页面 * 3.1.3 在Activity页面之间传递数据 1.??Bundle类 Bundle类是用于将字符串与某组件对象建立映射关系的组件。Bundle组件与Intent配合使用,可以在不同的Activity之间传递数据。Bundle类的常用方法如下。 * putString(String key, String value):把字符串用“键-值”对形式存放到Bundle对 象中。 * remove(String key):移除指定key的值。 * getString(String key):获取指定key的字符。 2.??Intent操作Bundle组件的方法 Intent操作绑定组件Bundle的方法如下。 * getExtras():获取Intent组件中绑定的Bundle对象。 * putExtras():把Bundle对象绑定到Intent组件上。 3. 应用Intent在不同的Activity之间传递数据 下面说明应用Intent与Bundle配合从一个Activity页面传递数据到另一Activity页面的方法。 (1)在页面Activity A端。 ① 创建Intent对象和Bundle对象: Intent intent = new Intent(); Bundle bundle = new Bundle(); ② 为Intent指定切换页面,用Bundle 存放“键-值”对数据: intent.setClass(MainActivity.this, SecondActivity.class); bundle.putString("text", txt.getText().toString()); ③ 将Bundle对象传递给Intent: intent.putExtras(bundle); (2)在另一页面Activity B端。 ① 从Intent中获取Bundle对象: bunde = this.getIntent().getExtras(); ② 从Bundle对象中按“键-值”对的键名获取对应数据值: String str = bunde.getString("text"); 在不同的Activity页面之间传递数据的过程如图3.5所示。 图3.5 应用Intent在Activity页面之间传递数据 【例3-2】 从第1个Activity页面传递数据到第2个Activity页面示例。 (1)设计第1个页面的界面布局activity_main.xml。 在第?1?个页面的界面布局中,设置一个文本标签和一个按钮,建立组件约束如图?3.6所示。 图3.6 建立第1个页面的界面布局和组件约束 设置编辑框EditText的background属性值: android:background = "@android:drawable/editbox_background"。 (2)设计第1个页面的控制程序MainActivity.java。 1 package com.example.ex3_2; 2 import androidx.appcompat.app.AppCompatActivity; 3 import android.content.Intent; 4 import android.os.Bundle; 5 import android.view.View; 6 import android.widget.Button; 7 import android.widget.EditText; 8 public class MainActivity extends AppCompatActivity 9 { 10 EditText txt1; 11 Button btn1; 12 @Override 13 protected void onCreate(Bundle savedInstanceState) 14 { 15 super.onCreate(savedInstanceState); 16 setContentView(R.layout.activity_main); 17 txt1 = (EditText)findViewById(R.id.editText); 18 btn1 = (Button)findViewById(R.id.button1); 19 btn1.setOnClickListener(new mClick()); 20 } 21 class mClick implements View.OnClickListener{ 22 @Override 23 public void onClick(View v) { 24 Intent intent = new Intent(); 25 intent.setClass(MainActivity.this, SecondActivity.class); 26 Bundle bundle = new Bundle(); 27 bundle.putString("text", txt1.getText().toString()); 28 intent.putExtras(bundle); 29 startActivity(intent); 30 } 31 } 32 } (3)设计第2个页面的界面布局文件activity_second.xml。 在项目中生成第2个页面,在页面中设置一个文本标签和一个按钮,其界面布局如图?3.7所示。 图3.7 建立第2个页面的界面布局和组件约束 (4)设计第2个页面的控制文件secondActivity.java,其代码如下。 1 package com.example.ex3_2; 2 import androidx.appcompat.app.AppCompatActivity; 3 import android.content.Intent; 4 import android.os.Bundle; 5 import android.view.View; 6 import android.widget.Button; 7 import android.widget.EditText; 8 public class MainActivity extends AppCompatActivity 9 { 10 TextView txt2; 11 Button btn2; 12 Intent intent2; 13 Bundle bundle2; 14 @Override 15 protected void onCreate(Bundle savedInstanceState) 16 { 17 super.onCreate(savedInstanceState); 18 setContentView(R.layout.activity_main); 19 txt2 = (TextView)findViewById(R.id.textView); 20 btn2 = (Button)findViewById(R.id.button2); 21 intent2 = this.getIntent(); 22 bundle2 = intent2.getExtras(); 23 String str = bundle2.getString("text"); 24 txt2.setText(str); 25 btn2.setOnClickListener(new mClick()); 26 } 27 //定义返回到前一页面的监听接口事件 28 class btnclock2 implements OnClickListener 29 { 30 public void onClick(View v) 31 { 32 Intent intent3 = new Intent(); 33 intent3.setClass(SecondActivity.this, MainActivity.class); 34 startActivity(intent3); 35 } 36 } 37 } 运行程序,在第1个页面的编辑框中输入数据,点击按钮后跳转到第2个页面,数据也随之传递到第2个页面,如图3.8所示。 图3.8 数据在不同Activity页面之间传递 ?3.2 菜单设计 一个菜单(Menu)由多个菜单选项组成,选择一个菜单项就可以引发一个动作事件。 在Android系统中,菜单可以分为3类:选项菜单(Option??Menu)、上下文菜单(Context Menu)和子菜单(Sub Menu)。下面主要介绍选项菜单和上下文菜单的设计方法,由于子菜单的设计方法基本与选项菜单相同,这里就不赘述了。 * 3.2.1 选项菜单 选项菜单需要通过按下设备的Menu键来显示。当按下设备上的Menu键后,在屏幕底部会弹出一个菜单,这个菜单称为选项菜单(Option Menu)。 1.??Activity中创建菜单的方法 设计选项菜单需要用到Activity中的onCreateOptionMenu(Menu menu)方法,用于建立菜单并且在菜单中添加菜单项;还需要用到Activity中的onOptionsItemSelected(MenuItem item)方法,用于响应菜单事件。Activity实现选项菜单的方法如表3-1所示。 表3-1 Activity实现选项菜单的方法 方 法 说 明 onCreateOptionMenu(Menu menu) 用于初始化菜单,menu为Menu对象实例 onPrepareOptionsMenu(Menu menu) 改变菜单状态,在菜单显示前调用 onOptionsMenuClosed(Menu menu) 菜单被关闭时调用 onOptionsItemSelected(MenuItem item) 菜单项被点击时调用,即菜单项的监听方法 2. 菜单Menu 设计选项菜单需要用到Menu、MenuItem接口。一个Menu对象代表一个菜单,在 Menu对象中可以添加菜单项MenuItem对象,也可以添加子菜单Sub Menu。 菜单Menu使用add(int groupId, int itemId, int order, CharSequence title) 方法添加一个菜单项,add()方法中的4个参数如下。 (1)groupId(组别):如果不分组就写Menu.NONE。 (2)itemId(id):很重要,Android根据这个id来确定不同的菜单。 (3)order(顺序):哪个菜单项在前面由这个参数的大小决定。 (4)title(标题):菜单项的显示文本。 3. 创建选项菜单的步骤 创建选项菜单的步骤如下: (1)重写Activity的onCreateOptionMenu(Menu menu)方法,当菜单第一次被打开时 调用。 (2)调用Menu的add( )方法添加菜单项(MenuItem)。 (3)重写Activity的onOptionsItemSelected(MenuItem item)方法,当菜单项(MenuItem)被选择时来响应事件。 【例3-3】 选项菜单应用示例。 设计一个选项菜单应用的示例程序,其运行结果如图3.9所示。 (1)设计界面布局文件activity_main.xml。 在界面布局文件中设置一个文本标签,用于显示选择的菜单项。 图3.9 菜单示例 (2)设计事件处理的控制程序MainActivity.java。 控制程序MainActivity.java的源代码如下: 1 package com.example.ex3_3; 2 import androidx.appcompat.app.AppCompatActivity; 3 import android.os.Bundle; 4 import android.view.Menu; 5 import android.view.MenuItem; 6 import android.widget.TextView; 7 public class MainActivity extends AppCompatActivity 8 { 9 TextView txt; 10 @Override 11 public void onCreate(Bundle savedInstanceState) 12 { 13 super.onCreate(savedInstanceState); 14 setContentView(R.layout.activity_main); 15 txt = (TextView)findViewById(R.id.TextView1); 16 } 17 public boolean onCreateOptionsMenu(Menu menu) 18 { 19 // 调用父类方法来加入系统菜单 20 super.onCreateOptionsMenu(menu); 21 // 添加菜单项 22 menu.add( 23 1, //组号 24 1, //唯一的id 25 1, //序号 26 "菜单项1"); //菜单项标题 27 menu.add( 1, 2, 2, "菜单项2"); 28 menu.add( 1, 3, 3, "菜单项3"); 29 menu.add( 1, 4, 4, "菜单项4"); 30 return true; 31 } 32 public boolean onOptionsItemSelected(MenuItem item) 33 { 34 String title = "选择了" + item.getTitle().toString(); 35 switch (item.getItemId()) 36 { //响应每个菜单项(通过菜单项的id) 37 case 1: 38 txt.setText(title); 39 break; 40 case 2: 41 txt.setText(title); 42 break; 43 case 3: 44 txt.setText(title); 45 break; 46 case 4: 47 txt.setText(title); 48 break; 49 default: 50 //没有处理的事件交给父类来处理 51 return super.onOptionsItemSelected(item); 52 } 53 return true; 54 } 55 } * 3.2.2 上下文菜单 Android系统中的上下文菜单类似于计算机上的右键菜单。在为一个视图注册了上下文菜单之后,长按(两秒左右)这个视图对象就会弹出一个浮动菜单,即上下文菜单。任何视图都可以注册上下文菜单,最常见的是用于列表视图ListView的item。 创建一个上下文菜单的步骤如下: (1)重写Activity 的 onCreateContenxtMenu()方法,调用Menu的add方法添加菜单 项(MenuItem)。 (2)??重写Activity的onContextItemSelected()方法,响应上下文菜单菜单项的单击事件。 (3)调用Activity 的 registerForContextMenu()方法,为视图注册上下文菜单。 【例3-4】 上下文菜单应用示例。 设计一个上下文菜单应用的示例程序,其运行结果如图3.10所示。 (1)设计界面布局文件activity_main.xml。 在界面布局文件中设置3个文本标签,用于显示选择项,建立其约束如图3.11所示。 图3.10 上下文菜单应用示例 图3.11 建立3个文本标签的约束 (2)设计事件处理的控制程序MainActivity.java。 控制程序MainActivity.java的源代码如下: 1 package com.example.ex3_4; 2 import androidx.appcompat.app.AppCompatActivity; 3 import android.os.Bundle; 4 import android.view.Menu; 5 import android.view.MenuItem; 6 import android.view.ContextMenu; 7 import android.widget.TextView; 8 import android.view.View; 9 public class MainActivity extends AppCompatActivity 10 { 11 TextView txt1, txt2, txt3; 12 private static final int item1 = Menu.FIRST; 13 private static final int item2 = Menu.FIRST+1; 14 private static final int item3 = Menu.FIRST+2; 15 String str[] = {"黑暗天使", "战神觉醒", "渡劫修仙"}; 16 @Override 17 public void onCreate(Bundle savedInstanceState) 18 { 19 super.onCreate(savedInstanceState); 20 setContentView(R.layout.activity_main); 21 txt1 = (TextView)findViewById(R.id.TextView1); 22 txt2 = (TextView)findViewById(R.id.textView2); 23 txt3 = (TextView)findViewById(R.id.textView3); 24 txt1.setText(str[0].toString()); 25 txt2.setText(str[1].toString()); 26 txt3.setText(str[2].toString()); 27 registerForContextMenu(txt1); 28 registerForContextMenu(txt2); 29 registerForContextMenu(txt3); 30 } 31 //上下文菜单,本例会通过长按条目激活上下文菜单 32 @Override 33 public void onCreateContextMenu(ContextMenu menu, View view, 34 ContextMenuInfo menuInfo) 35 { 36 menu.setHeaderTitle("游戏人物简介"); 37 //添加菜单项 38 menu.add(0, item1, 0, "武功"); 39 menu.add(0, item2, 0, "战斗力"); 40 menu.add(0, item3, 0, "经典语录"); 41 } 42 //菜单单击响应 43 @Override 44 public boolean onContextItemSelected(MenuItem item) 45 { 46 //获取当前被选择的菜单项的信息 47 switch(item.getItemId()) 48 { 49 case item1: 50 //在这里添加处理代码 51 break; 52 case item2: 53 //在这里添加处理代码 54 break; 55 case item3: 56 //在这里添加处理代码 57 break; 58 } 59 return true; 60 } 61 } ?3.3 对话框 对话框是一个有边框、有标题栏的独立存在的容器,在应用程序中经常使用对话框组件来进行人机交互。Android系统提供了4种常用对话框。 * AlertDialog:消息对话框。 * ProgressDialog:进度条对话框。 * DatePickerDialog:日期选择对话框。 * TimePickerDialog:时间选择对话框。 下面逐一介绍这些对话框的使用方法。 * 3.3.1 消息对话框 AlertDialog对话框是应用程序设计中最常用的对话框之一。AlertDialog对话框的内容很丰富,使用AlertDialog类可以创建普通对话框、带列表的对话框以及带单选按钮和多选按钮的对话框。AlertDialog类的常用方法如表3-2所示。 表3-2 AlertDialog类的常用方法 方 法 说 明 AlertDialog.Builder(Context) 对话框Builder对象的构造方法 create(); 创建AlertDialog对象 setTitle(); 设置对话框标题 setIcon(); 设置对话框图标 setMessage(); 设置对话框的提示信息 setItems(); 设置对话框要显示的一个list setPositiveButton(); 在对话框中添加yes按钮 setNegativeButton(); 在对话框中添加no按钮 show(); 显示对话框 dismiss(); 关闭对话框 创建AlertDialog对象需要使用AlertDialog的内部类Builder。设计AlertDialog对话框的步骤如下。 (1)用AlertDialog.Builder类创建对话框Builder对象。 Builder dialog=new AlertDialog.Builder(Context); (2)设置对话框的标题、图标、提示信息内容、按钮等。 dialog.setTitle("普通对话框"); dialog.setIcon(R.drawable.icon1); dialog.setMessage("一个简单的提示对话框"); dialog.setPositiveButton("确定", new okClick()); (3)创建并显示AlertDialog对话框对象。 dialog.create(); dialog.show(); 如果在对话框内部设置了按钮,还需要为其设置事件监听OnClickListener。 【例3-5】 消息对话框应用示例。 在本例中设计了两种形式的对话框程序,一种是发出提示信息的普通对话框,另一种是用户登录对话框。 在用户登录对话框中,设计了用户登录的布局文件long.xml,供用户输入相关验证 信息。 在创建的应用程序框架中,将事先准备的图像文件icon1.jpg、icon2.jpg复制到res\drawable目录下,用作对话框的图标。 程序的运行结果如图3.12所示。 图3.12 AlertDialog对话框 (1)设计界面布局文件activity_main.xml。 在界面中设置两个按钮,建立约束如图3.13所示。 图3.13 AlertDialog对话框的约束 (2)设计登录对话框的界面布局文件login.xml。 新建一个xml文件,命名为login.xml,其代码如下: 1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" > 6 <TextView 7 android:id="@+id/user" 8 android:layout_width="wrap_content" 9 android:layout_height="wrap_content" 10 android:text="用户名" 11 android:textSize="18sp"/> 12 <EditText 13 android:id="@+id/userEdit" 14 android:layout_width="match_parent" 15 android:layout_height="wrap_content" 16 android:textSize="18sp"/> 17 <TextView 18 android:id="@+id/textView" 19 android:layout_width="match_parent" 20 android:layout_height="wrap_content" 21 android:text="密码" 22 android:textSize="18sp"/> 23 <EditText 24 android:id="@+id/paswdEdit" 25 android:layout_width="match_parent" 26 android:layout_height="wrap_content" 27 android:textSize="18sp"/> 28 </LinearLayout> (3)设计控制文件MainActivity.java。 1 package com.example.ex3_5; 2 import androidx.appcompat.app.AppCompatActivity; 3 import android.os.Bundle; 4 import android.app.AlertDialog; 5 import android.content.DialogInterface; 6 import android.view.View; 7 import android.widget.Button; 8 import android. widget.EditText; 9 import android.widget.LinearLayout; 10 import android.widget.Toast; 11 public class MainActivity extends AppCompatActivity 12 { 13 Button btn1, btn2; 14 LinearLayout login; 15 @Override 16 public void onCreate(Bundle savedInstanceState) 17 { 18 super.onCreate(savedInstanceState); 19 setContentView(R.layout.activity_main); 20 btn1 = (Button)findViewById(R.id.button1); 21 btn2 = (Button)findViewById(R.id.button2); 22 btn1.setOnClickListener(new mClick()); 23 btn2.setOnClickListener(new mClick()); 24 } 25 class mClick implements OnClickListener 26 { 27 Builder dialog=new AlertDialog.Builder(MainActivity.this); 28 @Override 29 public void onClick(View v) 30 { 31 if(v == btn1) 32 { 33 //设置对话框的标题 34 dialog.setTitle("警告"); 35 //设置对话框的图标 36 dialog.setIcon(R.drawable.icon1); 37 //设置对话框显示的内容 38 dialog.setMessage("本项操作可能导致信息泄露!"); 39 //设置对话框的“确定”按钮 40 dialog.setPositiveButton("确定", new okClick()); 41 //创建对象框 42 dialog.create(); 43 //显示对象框 44 dialog.show(); 45 } 46 else if(v == btn2) 47 { 48 login = (LinearLayout)getLayoutInflater() 49 .inflate(R.layout.login, null); 50 dialog.setTitle("用户登录").setMessage("请输入用户名和密码") 51 .setView(login); 52 dialog.setPositiveButton("确定", new loginClick()); 53 dialog.setNegativeButton("退出", new exitClick()); 54 dialog.setIcon(R.drawable.icon2); 55 dialog.create(); 56 dialog.show(); 57 } 58 } 59 } 60 /* 普通对话框的“确定”按钮事件 */ 61 class okClick implements DialogInterface.OnClickListener 62 { 63 @Override 64 public void onClick(DialogInterface dialog, int which) 65 { 66 dialog.cancel(); 67 } 68 } 69 /* 输入对话框的“确定”按钮事件 */ 70 class loginClick implements DialogInterface.OnClickListener 71 { 72 EditText txt; 73 @Override 74 public void onClick(DialogInterface dialog, int which) 75 { 76 txt = (EditText)login.findViewById(R.id.paswdEdit); 77 //取出输入编辑框的值与密码“admin”比较 78 if((txt.getText().toString()).equals("admin")) 79 Toast.makeText(getApplicationContext(), 80 "登录成功", Toast.LENGTH_SHORT).show(); 81 else 82 Toast.makeText(getApplicationContext(), 83 "密码错误", Toast.LENGTH_SHORT).show(); 84 dialog.dismiss(); 85 } 86 } 87 /* 输入对话框的“退出”按钮事件 */ 88 class exitClick implements DialogInterface.OnClickListener 89 { 90 @Override 91 public void onClick(DialogInterface dialog, int which) 92 { 93 MainActivity.this.finish(); 94 } 95 } 96 } 对于程序的第48、49行: login = (LinearLayout)getLayoutInflater() .inflate(R.layout.login, null); 这里inflate()是将组件从一个XML中定义的布局找出来。 在一个Activity中如果直接用findViewById(),对应的是setConentView()中的那个layout中的组件(程序第19行中的R.layout.activity_main)。如果Activity中用到其他layout布局,比如对话框上的layout,还要设置对话框上的layout中的组件(像图片ImageView、文字TextView)上的内容,这就必须用inflate()先将对话框上的layout找出来,然后再用这个layout对象找到它上面的组件。 * 3.3.2 其他几种常用对话框 1. 进度条对话框 Android系统有一个ProgressDialog类,它继承于AlertDialog类,综合了进度条与对话框的特点,使用起来非常简单。ProgressDialog类的继承关系如图3.14所示。 ProgressDialog类的常用方法如表3-3所示。 表3-3 ProgressDialog类的常用方法 方 法 说 明 getMax() 获取对话框进度的最大值 getProgress() 获取对话框当前的进度值 onStart() 开始调用对话框 setMax(int max) 设置对话框进度的最大值 setMessage(CharSequence message) 设置对话框的文本内容 setProgress(int value) 设置对话框当前的进度 show(Context context, CharSequence title, CharSequence message) 设置对话框的显示内容和方式 ProgressDialog(Context context) 对话框的构造方法 2. 日期对话框和时间对话框 日期选择类DatePickerDialog和时间选择类TimePickerDialog都继承于AlertDialog类,一般用于日期和时间的设定,它们的常用方法如表3-4所示。 表3-4 日期和时间选择对话框的常用方法 方 法 说 明 updateDate(int year, int monthOfYear, int dayOfMonth) 设置DatePickerDialog对象的当前日期 onDateChanged(DatePicker view, int year, int month, int day) 修改DatePickerDialog对象的日期 updateTime(int hourOfDay, int minutOfHour) 设置TimePickerDialog对象的时间 onTimeChanged(TimePicker view, int hourOfDay, int minute) 修改TimePickerDialog对象的时间 【例3-6】 进度对话框、日期对话框和时间对话框示例。 (1)设计用户界面程序activity_main.xml。 在界面设计中,设置3个按钮,分别用于打开进度对话框、日期对话框和时间对话框。 (2)设计控制程序MainActivity.java。 1 package com.example.ex3_6; 2 import androidx.appcompat.app.AppCompatActivity; 3 import android.os.Bundle; 4 package com.example.ex3_6; 5 import android.app.Activity; 6 import android.app.DatePickerDialog; 7 import android.app.ProgressDialog; 8 import android.app.TimePickerDialog; 9 import android.app.DatePickerDialog.OnDateSetListener; 10 import android.app.TimePickerDialog.OnTimeSetListener; 11 import android.view.View; 12 import android.view.View.OnClickListener; 13 import android.widget.Button; 14 import android.widget.DatePicker; 15 import android.widget.TimePicker; 16 public class MainActivity extends Activity 17 { 18 Button btn1,btn2,btn3; 19 @Override 20 public void onCreate(Bundle savedInstanceState) 21 { 22 super.onCreate(savedInstanceState); 23 setContentView(R.layout.activity_main); 24 btn1=(Button)findViewById(R.id.button1); 25 btn2=(Button)findViewById(R.id.button2); 26 btn3=(Button)findViewById(R.id.button3); 27 btn1.setOnClickListener(new mClick()); 28 btn2.setOnClickListener(new mClick()); 29 btn3.setOnClickListener(new mClick()); 30 } 31 class mClick implements OnClickListener 32 { 33 int m_year = 2012; 34 int m_month = 1; 35 int m_day = 1; 36 int m_hour = 12, m_minute = 1; 37 @Override 38 public void onClick(View v) 39 { 40 if(v == btn1) 41 { 42 ProgressDialog d=new ProgressDialog (MainActivity.this); 43 d.setTitle("进度对话框"); 44 d.setIndeterminate(true); 45 d.setMessage("程序正在Loading..."); 46 d.setCancelable(true); 47 d.setMax(10); 48 d.show(); 49 } 50 else if(v == btn2) 51 { 52 //设置日期监听器 53 DatePickerDialog.OnDateSetListener dateListener = 54 new DatePickerDialog.OnDateSetListener() 55 { 56 @Override 57 public void onDateSet(DatePicker view, int year, 58 int month, int dayOfMonth) 59 { 60 m_year = year; 61 m_month = month;