zoukankan      html  css  js  c++  java
  • Android日期对话框NumberPicker的使用方法教程

    NumberPicker是Android3.0之后引入的一个控件。NumberPicker 是用于选择一组提前定义好数字的控件。比方时间hour的选择仅仅有0—23有效,则能够通过setMinValue和setMaxValue设定。

    使用该控件时需注意他的两个listener和一个formatter:一个listener用于监听当前value的变化;一个listener用于监听该控件的scroll状态;formatter用于格式化显示该控件中的value。

    以下逐一介绍这几个接口:

    1、NumberPicker.OnValueChangeListener :其函数public void onValueChange(NumberPicker picker, int oldVal, int newVal) ;oldVal前一个选中的值。newValue当前选中的值。

    2、NumberPicker.OnScrollListener其内部有三种scroll状态SCROLL_STATE_FLING 、 SCROLL_STATE_IDLE 、 SCROLL_STATE_TOUCH_SCROLL。

    SCROLL_STATE_TOUCH_SCROLL:用户按下去然后滑动。


    SCROLL_STATE_FLING: 相当于是SCROLL_STATE_TOUCH_SCROLL的兴许滑动操作。

    SCROLL_STATE_IDLE: NumberPicker不在滚动。

    3、NumberPicker.Formatter: 格式化显示数字,比如0—23格式化为00 — 23 。

    详细的格式在format函数中规定,例如以下所看到的:

    	public String format(int value) {  
            String Str = String.valueOf(value);  
            if (value < 10) {  
            	Str = "0" + Str;  
            }  
            return Str;  
        }  
    value值在0—23之间,小于10的数在前面加上“0”。

    介绍完NumberPicker后。就要实现我们今天的功能。首先先看效果图。例如以下所看到的:


    是不是很美丽那,这样以后我们的项目中须要这样的效果,就直接就能够拿来用了。要实现这样的效果当然要先看我们的布局了,事实上布局里面就三个NumberPicker例如以下所看到的:

    <?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:gravity="center"
        android:orientation="vertical" >
    
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:orientation="horizontal"
            android:paddingLeft="3.0dip" >
    
            <NumberPicker
                android:id="@+id/np_date"
                android:layout_width="120.0dip"
                android:layout_height="wrap_content"
                android:button="@null" />
    
            <NumberPicker
                android:id="@+id/np_hour"
                android:layout_width="50.0dip"
                android:layout_height="wrap_content"
                android:layout_marginLeft="5.0dip" />
    
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:text=":"
                android:textSize="20.0sp" />
    
            <NumberPicker
                android:id="@+id/np_minute"
                android:layout_width="50.0dip"
                android:layout_height="wrap_content" />
        </LinearLayout>
    
    </LinearLayout>
    就是这三个NumberPicker布局出我们刚才的效果,布局完毕我们就要找到这些控件。给他们加上监听。来实现一些功能。这里面是自己定义FrameLayout在直接填充布局做的。让我们来看看,例如以下所看到的:

    package com.zqy.datetimepicker.datedialog;
    
    import java.util.Calendar;
    
    import com.zqy.datetimepicker.R;
    
    
    import android.content.Context;
    import android.text.format.DateFormat;
    import android.widget.FrameLayout;
    import android.widget.NumberPicker;
    import android.widget.NumberPicker.OnValueChangeListener;
    
    public class DateTimePicker extends FrameLayout {
    	private final NumberPicker mDateSpinner;
    	private final NumberPicker mHourSpinner;
    	private final NumberPicker mMinuteSpinner;
    	private Calendar mDate;
    	private int mHour, mMinute;
    	private String[] mDateDisplayValues = new String[7];
    	private OnDateTimeChangedListener mOnDateTimeChangedListener;
    
    	public DateTimePicker(Context context) {
    		super(context);
    		/*
    		 *獲取系統時間 
    		 */
    		mDate = Calendar.getInstance();
    		mHour = mDate.get(Calendar.HOUR_OF_DAY);
    		mMinute = mDate.get(Calendar.MINUTE);
    		/**
    		 * 载入布局
    		 */
    		inflate(context, R.layout.datedialog, this);
    		/**
    		 * 初始化控件
    		 */
    		mDateSpinner = (NumberPicker) this.findViewById(R.id.np_date);
    		mDateSpinner.setMinValue(0);
    		mDateSpinner.setMaxValue(6);
    		updateDateControl();
    		mDateSpinner.setOnValueChangedListener(mOnDateChangedListener);
    
    		mHourSpinner = (NumberPicker) this.findViewById(R.id.np_hour);
    		mHourSpinner.setMaxValue(23);
    		mHourSpinner.setMinValue(0);
    		mHourSpinner.setValue(mHour);
    		mHourSpinner.setOnValueChangedListener(mOnHourChangedListener);
    
    		mMinuteSpinner = (NumberPicker) this.findViewById(R.id.np_minute);
    		mMinuteSpinner.setMaxValue(59);
    		mMinuteSpinner.setMinValue(0);
    		mMinuteSpinner.setValue(mMinute);
    		mMinuteSpinner.setOnValueChangedListener(mOnMinuteChangedListener);
    	}
    	/**
    	 * 
    	 * 控件监听器
    	 */
    	private NumberPicker.OnValueChangeListener mOnDateChangedListener = new OnValueChangeListener() {
    		@Override
    		public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
    			mDate.add(Calendar.DAY_OF_MONTH, newVal - oldVal);
    			/**
    			 * 更新日期
    			 */
    			updateDateControl();
    			/**
    			 * 给接口传值
    			 */
    			onDateTimeChanged();
    		}
    	};
    
    	private NumberPicker.OnValueChangeListener mOnHourChangedListener = new OnValueChangeListener() {
    		@Override
    		public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
    			mHour = mHourSpinner.getValue();
    			onDateTimeChanged();
    		}
    	};
    
    	private NumberPicker.OnValueChangeListener mOnMinuteChangedListener = new OnValueChangeListener() {
    		@Override
    		public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
    			mMinute = mMinuteSpinner.getValue();
    			onDateTimeChanged();
    		}
    	};
    
    	private void updateDateControl() {
    		/**
    		 * 星期几算法
    		 */
    		Calendar cal = Calendar.getInstance();
    		cal.setTimeInMillis(mDate.getTimeInMillis());
    		cal.add(Calendar.DAY_OF_YEAR, -7 / 2 - 1);
    		mDateSpinner.setDisplayedValues(null);
    		for (int i = 0; i < 7; ++i) {
    			cal.add(Calendar.DAY_OF_YEAR, 1);
    			mDateDisplayValues[i] = (String) DateFormat.format("MM.dd EEEE",
    					cal);
    		}
    		mDateSpinner.setDisplayedValues(mDateDisplayValues);
    		mDateSpinner.setValue(7 / 2);
    		mDateSpinner.invalidate();
    	}
    	
    	
    	/*
    	 *接口回调 參数是当前的View 年月日小时分钟
    	 */
    	public interface OnDateTimeChangedListener {
    		void onDateTimeChanged(DateTimePicker view, int year, int month,
    				int day, int hour, int minute);
    	}
    	/*
    	 *对外的公开方法 
    	 */
    	public void setOnDateTimeChangedListener(OnDateTimeChangedListener callback) {
    		mOnDateTimeChangedListener = callback;
    	}
    	
    	private void onDateTimeChanged() {
    		if (mOnDateTimeChangedListener != null) {
    			mOnDateTimeChangedListener.onDateTimeChanged(this,mDate.get(Calendar.YEAR), mDate.get(Calendar.MONTH),
    				mDate.get(Calendar.DAY_OF_MONTH), mHour, mMinute);
    		}
    	}
    }
    
    这段代码就是找到这三个控件。分别给他们setMinValue(),setMaxValue(),也就是最大值和最小值,设置完毕后,我们给他们三个分别加上监听setOnValueChangedListener以下有三个监听方法,在mOnDateChangedListener这种方法了多了一个updateDateControl()方法,这个updateDateControl()方法里面主要是月份和星期几的关系算法。

    写完这些,值也拿到了,可是我们须要把值传出去,以下我们又定义了一个接口来实现回调.接下来让我们在来看看对话框这个类,例如以下所看到的:

    package com.zqy.datetimepicker.datedialog;
    
    import java.util.Calendar;
    
    import com.zqy.datetimepicker.datedialog.DateTimePicker.OnDateTimeChangedListener;
    
    import android.app.AlertDialog;
    import android.content.Context;
    import android.content.DialogInterface;
    import android.content.DialogInterface.OnClickListener;
    import android.text.format.DateUtils;
    
    public class DateTimePickerDialog extends AlertDialog implements
    		OnClickListener {
    	private DateTimePicker mDateTimePicker;
    	private Calendar mDate = Calendar.getInstance();
    	private OnDateTimeSetListener mOnDateTimeSetListener;
    	@SuppressWarnings("deprecation")
    	public DateTimePickerDialog(Context context, long date) {
    		super(context);
    		mDateTimePicker = new DateTimePicker(context);
    		setView(mDateTimePicker);
    		/*
    		 *实现接口,实现里面的方法
    		 */
    		mDateTimePicker
    				.setOnDateTimeChangedListener(new OnDateTimeChangedListener() {
    					@Override
    					public void onDateTimeChanged(DateTimePicker view,
    							int year, int month, int day, int hour, int minute) {
    						mDate.set(Calendar.YEAR, year);
    						mDate.set(Calendar.MONTH, month);
    						mDate.set(Calendar.DAY_OF_MONTH, day);
    						mDate.set(Calendar.HOUR_OF_DAY, hour);
    						mDate.set(Calendar.MINUTE, minute);
    						mDate.set(Calendar.SECOND, 0);
    						/**
    						 * 更新日期
    						 */
    						updateTitle(mDate.getTimeInMillis());
    					}
    				});
    
    		setButton("设置", this);
    		setButton2("取消", (OnClickListener) null);
    		mDate.setTimeInMillis(date);
    		updateTitle(mDate.getTimeInMillis());
    	}
    	/*
    	 *接口回調  
    	 *控件 秒数
    	 */
    	public interface OnDateTimeSetListener {
    		void OnDateTimeSet(AlertDialog dialog, long date);
    	}
    	/**
    	 * 更新对话框日期
    	 * @param date
    	 */
    	private void updateTitle(long date) {
    		int flag = DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_SHOW_DATE
    				| DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_SHOW_TIME;
    		setTitle(DateUtils.formatDateTime(this.getContext(), date, flag));
    	}
    	/*
    	 * 对外公开方法让Activity实现
    	 */
    	public void setOnDateTimeSetListener(OnDateTimeSetListener callBack) {
    		mOnDateTimeSetListener = callBack;
    	}
    
    	public void onClick(DialogInterface arg0, int arg1) {
    		if (mOnDateTimeSetListener != null) {
    			mOnDateTimeSetListener.OnDateTimeSet(this, mDate.getTimeInMillis());
    		}
    	}
    }

    我们一行一行看。首先我们是继承AlertDialog。在以下我们new DateTimePicker,这个就是刚才写的类。我们这个类的对象实现我们刚才写的接口,把里面的值取到,尽管取到了,可是我们也不是在这里显示,所以我们还须要定义接口,让DateTimePickerDialog的对象去实现,以下就是我们的写的接口,我们写了那么多,仅仅为MainActivity里面的几行代码,让我们看看,例如以下所看到的:

    package com.zqy.datetimepicker.activity;
    
    import java.text.SimpleDateFormat;
    
    import com.zqy.datetimepicker.R;
    import com.zqy.datetimepicker.datedialog.DateTimePickerDialog;
    import com.zqy.datetimepicker.datedialog.DateTimePickerDialog.OnDateTimeSetListener;
    
    import android.app.Activity;
    import android.app.AlertDialog;
    import android.os.Bundle;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.Toast;
    
    public class MainActivity extends Activity {
    	private Button btn;
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.main);
    		btn = (Button) this.findViewById(R.id.button1);
    		btn.setOnClickListener(new OnClickListener() {
    			@Override
    			public void onClick(View v) {
    				showDialog();
    			}
    		});
    	}
    
    	public void showDialog() {
    		DateTimePickerDialog dialog = new DateTimePickerDialog(this,
    				System.currentTimeMillis());
    		/**
    		 * 实现接口
    		 */
    		dialog.setOnDateTimeSetListener(new OnDateTimeSetListener() {
    			public void OnDateTimeSet(AlertDialog dialog, long date) {
    				Toast.makeText(MainActivity.this,
    						"您输入的日期是:" + getStringDate(date), Toast.LENGTH_LONG)
    						.show();
    			}
    		});
    		dialog.show();
    	}
    
    	/**
    	 * 将长时间格式字符串转换为时间 yyyy-MM-dd HH:mm:ss
    	 * 
    	 */
    	public static String getStringDate(Long date) {
    		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    		String dateString = formatter.format(date);
    		return dateString;
    	}
    
    }
    首先我们还是new DateTimePickerDialog这个类,我们把系统时间传过去。这样时间对话框显示的就是系统时间了。我们用这个类的对象去实现我们刚才写的接口。实现里面的方法,我们又定义了一个 将长时间格式字符串转换为时间 yyyy-MM-dd HH:mm:ss的方法,这样我用一个Toast把接口里面的值弹出来。

    OK,这样我们就实现完毕了,有什么不明确的能够在以下留言。


    源代码下载,请点击这里







  • 相关阅读:
    如何控制input框!
    火车头采集器破解版
    记Angular与Django REST框架的一次合作(2):前端组件化——Angular
    拉勾网一些“震惊”的结论
    一个知乎重度用户眼中的知乎
    anthelion编译
    搜索引擎爬虫蜘蛛的USERAGENT大全
    Netty系列之Netty高性能之道
    python正则表达式
    Cookie的使用,详解,获取,无法互通、客户端获取Cookie、深入解析cookie
  • 原文地址:https://www.cnblogs.com/gavanwanggw/p/6782278.html
Copyright © 2011-2022 走看看