在圖形界面中,對(duì)話框是人機(jī)交互的一種重要形式,程序可以通過對(duì)話框進(jìn)行一些信息的提示,而用戶也可以通過對(duì)話框?qū)Τ绦蜻M(jìn)行一些簡(jiǎn)單的交互操作。
在Android中,所有的對(duì)話框都是從android.app.Dialog類繼承而來的,此類的繼承結(jié)構(gòu)如下:
java.lang.Object
android.app.Dialog
可以發(fā)現(xiàn)此類直接繼承自O(shè)bject類,與View類沒有任何繼承關(guān)系。
警告框(AlertDialog)是項(xiàng)目中最常見的對(duì)話框形式,是Dialog的直接子類。
如果想要實(shí)例化AlertDialog類,往往需要依靠其內(nèi)部類AlertDialog.Builder類完成。
下面通過一個(gè)最常見的返回鍵提示退出功能來演示一下其用法。
package org.yayun.demo;
//省略導(dǎo)入包
public class MainActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // 生命周期方法
super.setContentView(R.layout.main); // 設(shè)置要使用的布局管理器
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode==KeyEvent.KEYCODE_BACK){
this.exitDialog();
}
return super.onKeyDown(keyCode, event);
}
private void exitDialog() {
Dialog dialog=new AlertDialog.Builder(this).setTitle("程序退出?").setMessage("確定退出嗎?").setPositiveButton("退出", new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
MainActivity.this.finish();
}
}).setNegativeButton("取消", new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
}).create();//創(chuàng)建Dialog
dialog.show();//顯示對(duì)話框
}
}
這里覆寫了onKeyDown()方法,通過里面的keycode參數(shù)判斷當(dāng)前按下的鍵,若keyCode==KeyEvent.KEYCODE_BACK可以認(rèn)定按下了返回鍵,彈出對(duì)話框進(jìn)行提示,若選擇了positivebutton(退出)則執(zhí)行finish方法,退出應(yīng)用。
運(yùn)行實(shí)例如下:
這屬于比較簡(jiǎn)單的應(yīng)用,但是在實(shí)際開發(fā)中用到還比較多。
1.main.xml代碼如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:id="@+id/mych"
android:text=""
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/mytext"
android:text=""
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/mybut"
android:text="選擇水果"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
2.MainActivity.java如下:
package org.yayun.demo;
//省略導(dǎo)入包
public class MyDialogDemo extends Activity {
private Button mybut = null ; // 定義按鈕
private TextView mych = null ; // 定義文本
private TextView mytext = null ; // 定義文本
private String fruitData [] = new String[] { "蘋果", "西瓜", "水蜜桃" };
private String fruitDesc [] = new String[] {
"蘋果,植物類水果,多次花果,具有豐富的營養(yǎng)成分,有食療、輔助治療等功能。",
"西瓜(學(xué)名:Citrullus Lanatus,英文:Watermelon),屬葫蘆科,原產(chǎn)于非洲。",
"水蜜桃,在植物分類學(xué)上屬于薔薇科,梅屬,桃亞屬,為落葉小喬木。"} ;
private int chNum = 0 ; // 保存選項(xiàng)
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.main); // 調(diào)用布局管理器
this.mybut = (Button) super.findViewById(R.id.mybut) ; // 取得按鈕
this.mych = (TextView) super.findViewById(R.id.mych) ; // 取得文本
this.mytext = (TextView) super.findViewById(R.id.mytext) ; // 取得文本
this.mybut.setOnClickListener(new OnClickListenerImpl()) ; // 設(shè)置事件類
}
private class OnClickListenerImpl implements OnClickListener {
@Override
public void onClick(View view) {
Dialog dialog = new AlertDialog.Builder(MyDialogDemo.this)
.setIcon(R.drawable.pic_m)
.setTitle("請(qǐng)選擇你喜歡吃的水果?")
.setPositiveButton("確定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
MyDialogDemo.this.mych
.setText(MyDialogDemo.this.fruitData[MyDialogDemo.this.chNum]); // 設(shè)置選項(xiàng)的名稱
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
}).setSingleChoiceItems(MyDialogDemo.this.fruitData, 0, new DialogInterface.OnClickListener() {//setSingleChoiceItems()方法
@Override
public void onClick(DialogInterface dialog, int which) {
MyDialogDemo.this.mytext
.setText(MyDialogDemo.this.fruitDesc[which]);
MyDialogDemo.this.chNum = which ; // 保存選項(xiàng)的索引
}
}).create() ;
dialog.show() ;
}
}
}
這種顯示風(fēng)格用到setSingleChoiceItems()方法,其覆寫的onClick()方法中的參數(shù)which決定了當(dāng)前選擇的是哪一項(xiàng)。
運(yùn)行實(shí)例:
之前的對(duì)話框都是直接通過Activity程序進(jìn)行定義的,但是如果希望在對(duì)話框中顯示一些復(fù)雜的界面,例如編寫一個(gè)登陸提示對(duì)話框,就需要通過布局文件定義顯示組件,之后再將這些布局顯示引入到對(duì)話框中,而如果想要引入,則需要LayoutInflater類的支持。 1定義布局管理器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/mybut"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="登錄" />
</LinearLayout>
主布局文件很簡(jiǎn)單,只有一個(gè)Button 控件,點(diǎn)擊button控件彈出登錄框。
2.定義對(duì)話框所需的布局管理器login.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" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:layout_width="60dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="用戶名:" />
<EditText
android:id="@+id/edit_user"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="88"
android:text="yayun" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:layout_width="60dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="密碼:" />
<EditText
android:id="@+id/edit_passwd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="88"
android:password="true"
android:text="123456" />
</LinearLayout>
</LinearLayout>
3.定義MainActivity.java:
package org.yayun.demo;
//省略導(dǎo)入包
public class MyDialogDemo extends Activity {
private Button btn;
String string_userString;
String string_passwdString;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.main); // 調(diào)用布局管理器
btn=(Button)findViewById(R.id.mybut);
btn.setOnClickListener(new OnClickListenerImpl());
}
private class OnClickListenerImpl implements OnClickListener{
@Override
public void onClick(View v) {
LayoutInflater layoutInflater=LayoutInflater.from(MyDialogDemo.this);//獲得layoutInflater對(duì)象
View view=layoutInflater.from(MyDialogDemo.this).inflate(R.layout.login, null);//獲得view對(duì)象
EditText edit_user=(EditText)view.findViewById(R.id.edit_user);//獲取控件
EditText edit_passwd=(EditText)view.findViewById(R.id.edit_passwd);
string_userString=edit_user.getText().toString();
string_passwdString=edit_passwd.getText().toString();
Dialog dialog=new AlertDialog.Builder(MyDialogDemo.this).setTitle("用戶登錄").setView(view).setPositiveButton("登錄", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
if(string_userString.equals("yayun")&&string_passwdString.equals("123456")){
Toast.makeText(MyDialogDemo.this, "登錄成功", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(MyDialogDemo.this, "登錄失敗", Toast.LENGTH_SHORT).show();
}
}
}).setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// 取消按鈕事件
}
}).create();
dialog.show();
}
}
}
調(diào)用LayoutInflater的from方法獲取對(duì)象,這里L(fēng)ayoutInflater應(yīng)該采用了單例模式,然后調(diào)用其inflate()方法獲取view對(duì)象。通過view對(duì)象的findViewById()方法獲取兩個(gè)控件對(duì)象,通過這兩個(gè)控件對(duì)象獲取相關(guān)數(shù)值,進(jìn)行邏輯判斷登錄是否成功。
4.運(yùn)行實(shí)例:
主要進(jìn)行日期和時(shí)間的設(shè)置。
1.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/mybut"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="設(shè)置日期" />
<Button
android:id="@+id/mytext"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="" />
</LinearLayout>
2.MainActivity.java代碼如下:
package org.yayun.demo;
//省略導(dǎo)入包
public class MyDialogDemo extends Activity {
private Button btn;
private TextView textView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.main); // 調(diào)用布局管理器
btn=(Button)findViewById(R.id.mybut);
textView=(TextView)findViewById(R.id.mytext);
btn.setOnClickListener(new OnClickListenerImpl());
}
private class OnClickListenerImpl implements OnClickListener{
@Override
public void onClick(View v) {
Dialog dialog=new DatePickerDialog(MyDialogDemo.this, new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int monthOfYear,
int dayOfMonth) {
textView.setText("更新日期為:"+year+"年-"+(monthOfYear+1)+"月-"+dayOfMonth+"日");
}
}, 1990, 04, 01);
dialog.show();
}
}
}
實(shí)現(xiàn)了DatePickerDialog,并覆寫了onDateSet()方法,通過里面的year、monthOfYear和dayOfMonth參數(shù)獲得了更新后的年月日信息。
運(yùn)行實(shí)例:
TimePickerDialog對(duì)話框和DatePickerDialog對(duì)話框基本一樣。
先看一個(gè)簡(jiǎn)單的圈形進(jìn)度處理對(duì)話框,這個(gè)在開發(fā)中也十分常見,常用于登錄等待、網(wǎng)絡(luò)連接等待、數(shù)據(jù)刷新等待等,可以增加用戶友好度。
1.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/mybut"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="查找網(wǎng)絡(luò)" />
</LinearLayout>
2.MainActivity.java代碼如下:
package org.yayun.demo;
//省略導(dǎo)入包
public class MyDialogDemo extends Activity {
private Button btn;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.main); // 調(diào)用布局管理器
btn = (Button) findViewById(R.id.mybut);
btn.setOnClickListener(new OnClickListenerImpl());
}
private class OnClickListenerImpl implements OnClickListener {
@Override
public void onClick(View v) {
final ProgressDialog dialog = ProgressDialog.show(
MyDialogDemo.this, "請(qǐng)搜索網(wǎng)絡(luò)...", "請(qǐng)耐心等待...");// 之所以用final定義,主要目的是為了讓內(nèi)部類可以訪問方法中定義的參數(shù)。
new Thread() {
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
dialog.dismiss();
}
};
}.start();
}
}
}
實(shí)現(xiàn)了ProgressDialog,在內(nèi)部定義了一個(gè)線程用于模仿網(wǎng)絡(luò)請(qǐng)求。
運(yùn)行實(shí)例:
keyCode==KeyEvent.KEYCODE_BACK;setSingleChoiceItems()方法的使用;LayoutInflater layoutInflater=LayoutInflater.from(MyDialogDemo.this);//獲得layoutInflater對(duì)象View view=layoutInflater.from(MyDialogDemo.this).inflate(R.layout.login, null);//獲得view對(duì)象;setView()方法,設(shè)置顯示布局;setProgressStyle()方法設(shè)置等待對(duì)話框顯示樣式,incrementProgressBy()啟動(dòng)自增長(zhǎng)。