您的位置:首页 > 其它

五种简单Dialog的使用,以及时间,日期Dialog中onDateSet,onTimeSet被执行两次的Bug

2016-02-16 19:20 681 查看

今天放一些Dialog的小例子,共有5种基本的Dialog以及如何使用以及他们对应的回调函数的使用

---------------------------------------------------------------------------------

Xml文件,定义5个Button用来显示5种Dialog:

<Button
android:id="@+id/bt_common"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="普通dialog"
android:onClick="clickButton"/>
<Button
android:id="@+id/bt_progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="进度条"
android:onClick="clickButton"/>
<Button
android:id="@+id/bt_date"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="日期dialog"
android:onClick="clickButton"/>
<Button
android:id="@+id/bt_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="时间dialog"
android:onClick="clickButton"/>
<Button
android:id="@+id/bt_custom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="自定义idalog"
android:onClick="clickButton"/>


clickButton函数,里面分别用来显示5种Dialog,分开贴出来,一种一种的来看:

最普通的Dialog:



case R.id.bt_common:
// 普通dialog
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setIcon(android.R.drawable.dialog_frame);
builder.setTitle("提示");
builder.setMessage("是否退出?");
builder.setNegativeButton("取消", null);
builder.setPositiveButton("确定", new OnClickListener() {

@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
builder.show();
break;


普通的Dialog这样用就行了,特别简单。设置图片setIcon,设置标题内容setTitle,设置信息setMessage(就是图中主题内容),设置取消按钮与确定按钮。这里值得说一下的是setNegativeButton("取消",null);这里第二个参数也应该是监听函数,我们对取消不做任何措施,光让dialog消失就行了,所以填入null就代表着这个功能。

ProgressDialog类型的Dialog:



代码:

ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setIcon(R.drawable.ic_launcher);
progressDialog.setTitle("提示");
progressDialog.setMessage("正在拼命加载中....");
progressDialog.setCancelable(true);
progressDialog.show();
这种Dialog是这样直接new出来的,请注意每种dialog的名字不同以及获取对象上的区别。说一下setCancelable();这个方法,这是设置当dialog进度条显示出的时候,点击除Dialog本身之外的空白的地方这个Dialog是否会消失,设置true为可以消失,设置false为不可以。注意:如果设置为false不能取消时,请提供相应的退出方案,否则此dialog一直不能消失,用户的体验性会及恶劣。。。

DatePickerDialog类型的Dialog:



代码:

Calendar calendar = Calendar.getInstance();
int year = calendar.get(Calendar.YEAR);
int monthOfYear = calendar.get(Calendar.MONTH);
int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
DatePickerDialog datePickerDialog = new DatePickerDialog(this,
new OnDateSetListener() {

@Override
public void onDateSet(DatePicker view, int year,
int monthOfYear, int dayOfMonth) {
String date = year + "-" + (monthOfYear + 1) + "-"
+ dayOfMonth;
Toast.makeText(DialogActivity.this, date,
Toast.LENGTH_LONG).show();
Log.i("MainActivity", "OnDateSetListener---->");
}

}, year, monthOfYear, dayOfMonth) <span style="color:#FF0000;">{
@Override
protected void onStop() {
}
};</span>
datePickerDialog.show();


这种日期选择Dialog提供特别方便的选择日期的功能。Calender类不用说,常用的日期工具类。new DatePickerDialog(context, callBack, year, monthOfYear, dayOfMonth)参数列表略长,下面是每个参数的意义:

/**

             * 创建带有日期选择器的对话框

             *

             * context  上下文对象

             * callBack  OnDateSetListener监听器

             * year    默认年

             * monthOfYear 默认月份

             * dayOfMonth  默认的日期

             */

值得注意的是,在接口回调中

blic void onDateSet(DatePicker view, int year,int monthOfYear, int dayOfMonth)
monthOfYear是0-11月份,所以需要月份数据的时候,请+1;

TimePickerDialog类型的Dialog:



代码:

SimpleDateFormat format = new SimpleDateFormat("HH-mm-ss");
String date = format.format(new Date());
String[] array = date.split("-");
TimePickerDialog timePickerDialog = new TimePickerDialog(this,
new OnTimeSetListener() {

@Override
public void onTimeSet(TimePicker view, int hourOfDay,
int minute) {
String time = hourOfDay + ":" + minute;
Toast.makeText(DialogActivity.this, time,
Toast.LENGTH_LONG).show();
Log.i("MainActivity", "OnTimeSetListener---->");
}
}, Integer.parseInt(array[0]), Integer.parseInt(array[1]),
true) <span style="color:#FF0000;">{
@Override
protected void onStop() {
}
}</span>;
timePickerDialog.show();

这个时间Dialog和日期Dialog几乎一样,就不多说了,同样有标红处(<span style="color:#FF0000;"></span>扩起来的)的代码,下面会有特殊说明此处代码是什么意思。

自定义类型的Dialog:



代码:

AlertDialog.Builder builder2 = new AlertDialog.Builder(this);
builder2.setTitle("登陆");
View view = LayoutInflater.from(this).inflate(
R.layout.custom_dialog, null);
etUsername = (EditText) view.findViewById(R.id.et_username);
etPassword = (EditText) view.findViewById(R.id.et_password);
builder2.setView(view);
builder2.setNegativeButton("取消", null);
builder2.setPositiveButton("登陆", new OnClickListener() {

@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(
DialogActivity.this,
etPassword.getText().toString() + "\n"
+ etUsername.getText().toString(),
Toast.LENGTH_LONG).show();
}
});
builder2.show();


可以看出来设置标题按钮这些东西基本一样,回调函数是直接的OnClickListener()。只不过将自定义的布局通过setView()设置进去了。自定义的布局文件也很简单,两个EditText,通过LayoutInflater加载进来。

上面的日期和时间Dialog有标红处的代码,其实java基础好的人可以轻松看出来,那是匿名子类的写法,目的是为了重写父类TimePickerDialog,DatePickerDialog中的onStop方法。因为在android4,.1-4.3(经过测试的版本)中存在着一个bug。我们知道点击确定的时候,会分别回调函数onDateSet()与onTimeSet()。这样点击一次按钮竟然回调两次函数,显然是不合理的。但是代码的写法上又没有什么错误,为什么会出现这个问题呢。通过查看源码得知,点击确认按钮完,dialog的onStop()会被执行,

onStop()的源码:

@Override
protected void onStop() {
tryNotifyTimeSet();
super.onStop();
}
再查看按钮被点击时方法:

public void onClick(DialogInterface dialog, int which) {
tryNotifyTimeSet();
}


同样调用了tryNotifyTimeSet(),那这个方法又是什么?

private void tryNotifyTimeSet() {
if (mCallback != null) {
mTimePicker.clearFocus();
mCallback.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(),
mTimePicker.getCurrentMinute());
}
}
我的天呀,可以看出来,这就是onTimeSet()回调函数被执行了两次的罪魁祸首。知道问题了就好解决了,我们在创建实例的时候加上方法体,重写里面的onStop()方法就行了。这样相当于继承了TimePickerDialog类的子类的实例,但是只使用一次,没必要真的创建一个子类,所以使用匿名的方法,屏蔽了一下这个BUG。DatePickerDialog同理。

-------------------------------------

原创,转载请说明,有些地方写的不清楚,因为时间有限,不喜勿喷 -----Ade-rui
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: