五种简单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
相关文章推荐
- 39. Combination Sum LeetCode
- AOP的实现原理
- 04环信聊天界面 - 发送聊天消息
- light oj 1297 Largest Box
- HTTP Header 详解
- Selenium2中对于alert元素的操作
- js子窗口修改父窗口内容
- 114. Flatten Binary Tree to Linked List LeetCode
- 最大公约数和最小公倍数问题(天梯)
- mybatis-dao添加案例
- 在运行时使用反射分析对象
- Chartpter1 Install the MASM32 SDK
- nyoj1237 最大岛屿(河南省第八届acm程序设计大赛)
- Android InputStream.available()方法详解
- JAVA-数据库Date格式在前台JSP页面的获取
- 改变libvirt vm镜像的默认位置
- 101. Symmetric Tree 对称树,递归算法
- android java 如何判断一个url地址为有效url
- 新的一年,春暖花开
- 一起啃PRML - Preface 前言