重写DatePickerDialog 解决OnDateSetListener只有完成,没有取消回调问题

今天写项目,发现这个DatePickerDialog给他设置了OnDateSetListener,但是我没有点击设置,它却回调了,判断不出我是否点击了设置,查看了网上一些方法:

方法一:自定义view的方法:http://www.2cto.com/kf/201501/367678.html

方法二:setButton方法:http://www.it165.net/pro/html/201503/36757.html

浏览了一下这两个方法,觉得方法一太麻烦,方法二的mDialog.getDatePicker();只有3.1以上才可以使用,两个方法都不好,后来继续浏览其它网页,发现一个比较牛逼的代码,深受启发。

http://blog.csdn.net/OnlyOneCoder/article/details/25481505

((ViewGroup) ((ViewGroup) this.getDatePicker().getChildAt(0)).getChildAt(0)).getChildAt(2).setVisibility(View.GONE);

这方法是根据picker的view布局设置隐藏天的,那么我也可以试试找出picker的完成按钮对它设置回调,而不用自带那个!

首先,我需要一个工具找到picker的button的view或它的id,然后设置 setOnClickListener

不知道网上有没有,反正不需要多复杂,自己写一个:

public class ViewUtil {
	public static JSONObject getViewLayoutJson (View view) {
		if (view == null) {
			return new JSONObject();
		} else {
			JSONObject json = new JSONObject();
			json.put("classname", view.getClass().getName());
			json.put("width", view.getMeasuredWidth());
			json.put("height", view.getMeasuredHeight());
			json.put("top", view.getTop());
			json.put("visibility", view.getVisibility());
			json.put("id", view.getId());
			if (view instanceof ViewGroup) {
				JSONArray jsonarr = new JSONArray();
				ViewGroup vg = (ViewGroup)view;
				for (int i = 0; i < vg.getChildCount(); i++) {
					jsonarr.add(getViewLayoutJson(vg.getChildAt(i)));
				}
				json.put("subview", jsonarr);
			} else if (view instanceof TextView) {
				TextView tv = (TextView)view;
				json.put("text", tv.getText());
			}
			return json;
		}
	}
}

获取dialog布局的json数据:

JSONObject json = ViewUtil.getViewLayoutJson(dataDialog.getWindow().getDecorView());

String layout = json.toJSONString();

其中,寻找设置按钮,在英文系统中就是 “Done”,找到结果如下:

												{
													"classname" : "android.widget.Button",
													"height" : 0,
													"id" : 16908313,
													"text" : "Done",
													"top" : 0,
													"visibility" : 0,
													"width" : 0
												}

完成按钮对应的id是16908313,进入android.R.id类,找到这个id,

  // Field descriptor #8 I
  public static final int button1 = 16908313;

这个id对应的名字是button1

知道这个id后,我们开始设计自定义dialog:

pimport android.app.DatePickerDialog;
import android.content.Context;
import android.view.View;
import android.widget.DatePicker;

public class AppPickerDialog extends DatePickerDialog {
	private int chooiceYear, chooiceMonth, chooiceDay;
	private DatePicker picker;
	private Context mContent;
	private OnDateSetListener mCallBack;

	public AppPickerDialog(final Context context,
			final OnDateSetListener callBack, int year, int monthOfYear,
			int dayOfMonth) {
		super(context, callBack, year, monthOfYear, dayOfMonth);
		mContent = context;
	}

	@Override
	public void onDateChanged(DatePicker view, int year, int month, int day) {
		super.onDateChanged(view, year, month, day);
		picker = view;
		chooiceYear = year;
		chooiceMonth = month;
		chooiceDay = day;
	}

	/**
	 * 完成事件
	 * @param callBack
	 */
	public void setOnPositiveListener(OnDateSetListener callBack) {
		mCallBack = callBack;
	}

	@Override
	public void show() {
		super.show();

		this.getWindow().getDecorView().findViewById(android.R.id.button1)
				.setOnClickListener(new View.OnClickListener() {
					@Override
					public void onClick(View view) {
						dismiss();
						if (mCallBack!=null) {
							mCallBack.onDateSet(picker, chooiceYear, chooiceMonth,chooiceDay);
						}
					}
				});
	}
}

new的时候,不要传onDateSetListener事件(这个系统分法的,不好用),要另外set一个自己写的方法

最后使用方法:

			dataDialog = new AppPickerDialog(this, null,
					year0, // 传入年份
					month0, // 传入月份
					day0// 传入天数
			);
			dataDialog.setOnPositiveListener(new OnDateSetListener() {
				@Override
				public void onDateSet(DatePicker dp, int year,int month, int dayOfMonth) {
					calendar.setTimeInMillis(System.currentTimeMillis());
					calendar.set(year, month, dayOfMonth, 0, 0, 0);
					if (calendar.getTimeInMillis() > System.currentTimeMillis()) {
						ToastUtil.showMessage(getActivity(), "请输入正确的时间!");
						return;
					}
					year0 = year;
					month0 = month;
					day0 = dayOfMonth;
					mq.id(R.id.birthday).text(year + "-" + (month+1) + "-" + dayOfMonth);
				}
			});
			dataDialog.show();
			

大功告成,解决的简单粗暴。

((

时间: 2024-10-02 05:42:29

重写DatePickerDialog 解决OnDateSetListener只有完成,没有取消回调问题的相关文章

重写ListView解决ListView内部ViewPaper滑动事件冲突问题

很简单 重写ListView 其他类似问题解决ScrollView嵌套ViewPager出现的滑动冲突问题 http://blog.csdn.net/zhangyiacm/article/details/37903071 package com.zy.myview; import android.content.Context; import android.util.AttributeSet; import android.view.GestureDetector; import androi

使用IDEA在引入Schema空间时报错URI is not registered解决方法以及Idea @Autowired取消提示 方法

使用IDEA在引入Schema空间时报错URI is not registered解决方法以及Idea @Autowired取消提示 方法   Idea @Autowired取消提示 spring bean通过@Autowired注入,spring auto scan配置,在编辑情况下,无法找不到对应的bean,于是提示找不到对应bean的错误. 但build项目是能正常运行的. 可在File – Settings – Inspections.在Spring Model – Autowring

HttpRequest重写,解决资源战胜/链接超时/分块下载事件通知 问题。

using System; using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.IO.Compression; using System.Linq; using System.Net; using System.Text; using System.Web; namespace MyApi { public class HttpRequest { public H

解决微信OAuth2.0网页授权回调域名只能设置一个的问题

https://github.com/HADB/GetWeixinCode GetWeixinCode 使用方法 部署get-weixin-code.html至你的微信授权回调域名的目录下,例如http://wx.abc.com/get-weixin-code.html 在其他页面的使用方式如下,类似于直接通过微信回调的方式,只是将回调地址改成了get-weixin-code.html的地址,另外省 去了response_type参数(因为它只能为code)以及#wechat_redirect的

解决使用Touch ID API在回调时界面“长时间卡住”的问题

Touch ID是iOS8上新公开的API,关于详细介绍和用法可以看CocoaChina的这两篇文章:上 和 下,在此篇文章中不在赘述. 我在app中需要的效果是如果touch id验证通过,则页面push到下一个viewController,否则本视图的数字密码输入框becomeFirstResponder.研究过touch id的人应该知道,这段代码大概会这么实现: 1 LAContext *context = [[LAContext alloc] init]; 2 NSError *err

Async.js解决Node.js操作MySQL的回调大坑

因为JavaScript语言异步特性.在使用Node.js运行非常多操作时都会使用到回调函数,当中就包含訪问数据库.假设代码中的业务逻辑略微复杂一点,回调一层层嵌套.那么代码非常easy进入Callback Hell,不管对写代码的人还是阅读代码的人,都是精神上的折磨. 比如对MySQL的一个事务操作,插入一条posts并插入一条log: var title = 'It is a new post'; connection.beginTransaction(function(err) { if

layui 时间插件laydate ,取消回调

背景:转型新公司不再是做前端展示H5之类的东西,主要业务是后台数据读取和插件搭建前端页面,接触的第一个老项目是layui制作的,由于业务需求,需要用到时间插件以下为时间插件的一些用法------------>>>>>>> 第一步.layui时间插件laydate本身是没有回调函数的,需要在latdate找到下面这段代码 //清空 as.oclear = S('#laydate_clear'); Dates.on(as.oclear, 'click', functi

Android笔记——date&amp;time(日期时间选择对话框)

TimePickerDialog(时间选择对话框) 创建TimePickerDialog时间选择对话框: 1.创建一个类继承DialogFragement 2.重写onCreateDialog()方法,返回一个TimePickerDialog对象 3.实现TimePickerDialog的OnTimeSetListener接口来接收一个回调,当用户设置时间 DatePickerDialog(日期选择对话框) 创建DatePickerDialog日期选择对话框: 1.创建一个类继承DialogFr

DatePickerDialog执行两次问题

这几天学习使用DatePickerDialog发现在获取日期后会执行两次,在一些高版本会出现,低版本反而没有,在查询了一些别人写的文章,问题在于高版本的的日期选择器的onStop方法会在执行一次,解决方法就是重写DatePickerDialog public static class ExDatePickDialog extends DatePickerDialog {      public ExDatePickDialog(Context context, OnDateSetListener