安卓(Android)实现选择时间功能

所属分类: 软件编程 / Android 阅读数: 2005
收藏 0 赞 0 分享

前言

由于大部分android初级教程都没教怎么选择时间,初学者碰到这种难免会有些不知所措,难道要让用户自己输入日期时间?先不说用户体验不好,处理用户输入各式各样的日期格式也要花好大一番功夫,下面看看如何实现android选择时间的功能。

android 6.0 中的运行效果


TimePickerDialog和DatePickerDialog介绍

系统封装好了两个类可以供我们直接调用,TimepickerDialog用于选择时间,DatePickerDialog用于选择日期。

TimePikckerDialog的构造方法

public TimePickerDialog(Context context, OnTimeSetListener listener, int hourOfDay, int minute, boolean is24HourView)

     1、第一个参数接受一个context信息

     2、第二个参数为当选择时间完成后执行的回调接口

     3、第三个参数和第四个参数为初始化的时间

     4、第四个参数选择true代表24小时制,false代表12小时制

DatePickerDialog构造方法

public DatePickerDialog(Context context, OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth)

      1、第一个参数接受context信息

      2、第二个参数为日期选择完成后的回掉接口

      3、最后三个参数分别为初始化的年月日

可以看出两者的构造方法基本相差不多,由于两者都是继承自AlertDialog,所以得到两者对象后只要调用它们的show()方法即可将选择框弹出。

具体实现

有两种实现方式,一种是直接在Activity中使用,还有一种是通过FragmentDialog使用。

直接在Activity中使用比较简单,不过代码会比较乱,通过FragmentDialog管理的使用方式会比较优雅,而且便于管理。

直接在Activity中使用

布局文件,里面就一个TextView用于显示所选时间

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context="com.example.testdemo.TestActivity">

  <TextView
    android:layout_centerInParent="true"
    android:textSize="20sp"
    android:id="@+id/time_text"
    android:text="点此选择时间"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

</RelativeLayout>

Activity文件:

public class TestActivity extends AppCompatActivity {

  private TextView timeText;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_test);
    timeText = (TextView) findViewById(R.id.time_text);
    //为TextView设置点击事件
    timeText.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        //将timeText传入用于显示所选择的时间
        showDialogPick((TextView) v);
      }
    });
  }
  //将两个选择时间的dialog放在该函数中
  private void showDialogPick(final TextView timeText) {
    final StringBuffer time = new StringBuffer();
    //获取Calendar对象,用于获取当前时间
    final Calendar calendar = Calendar.getInstance();
    int year = calendar.get(Calendar.YEAR);
    int month = calendar.get(Calendar.MONTH);
    int day = calendar.get(Calendar.DAY_OF_MONTH);
    int hour = calendar.get(Calendar.HOUR_OF_DAY);
    int minute = calendar.get(Calendar.MINUTE);
    //实例化TimePickerDialog对象
    final TimePickerDialog timePickerDialog = new TimePickerDialog(TestActivity.this, new TimePickerDialog.OnTimeSetListener() {
      //选择完时间后会调用该回调函数
      @Override
      public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
        time.append(" " + hourOfDay + ":" + minute);
        //设置TextView显示最终选择的时间
        timeText.setText(time);
      }
    }, hour, minute, true);
    //实例化DatePickerDialog对象
    DatePickerDialog datePickerDialog = new DatePickerDialog(TestActivity.this, new DatePickerDialog.OnDateSetListener() {
      //选择完日期后会调用该回调函数
      @Override
      public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
        //因为monthOfYear会比实际月份少一月所以这边要加1
        time.append(year + "-" + (monthOfYear+1) + "-" + dayOfMonth);
        //选择完日期后弹出选择时间对话框
        timePickerDialog.show();
      }
    }, year, month, day);
    //弹出选择日期对话框
    datePickerDialog.show();
  }

}

到此,点击运行就可以看效果了:)

通过FragmentDialog使用

为什么要用DialogFragment

      1、用DialogFragment管理对话框是官方推介的使用方式。

       2、使用DialogFragment管理对话框也方便代码的重用。

通过FragmentDialog实现步骤

DatePickerFragment类:

public class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener{
  private String date;
  @Override
  public Dialog onCreateDialog(Bundle savedInstanceState) {
    //得到Calendar类实例,用于获取当前时间
    Calendar calendar = Calendar.getInstance();
    int year = calendar.get(Calendar.YEAR);
    int month = calendar.get(Calendar.MONTH);
    int day = calendar.get(Calendar.DAY_OF_MONTH);
    //返回DatePickerDialog对象
    //因为实现了OnDateSetListener接口,所以第二个参数直接传入this
    return new DatePickerDialog(getActivity(), this, year, month, day);
  }

  //实现OnDateSetListener接口的onDateSet()方法
  @Override
  public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
    //这样子写就将选择时间的fragment和选择日期的fragment完全绑定在一起
    //使用的时候只需直接调用DatePickerFragment的show()方法
    //即可选择完日期后选择时间
    TimePickerFragment timePicker = new TimePickerFragment();
    timePicker.show(getFragmentManager(), "time_picker");
    //将用户选择的日期传到TimePickerFragment
    date = year + "年" + (monthOfYear+1) + "月" + dayOfMonth + "日";
    timePicker.setTime(date);
  }
}

TimePickerFragment类:

//实现OnTimeSetListener接口
public class TimePickerFragment extends DialogFragment implements TimePickerDialog.OnTimeSetListener{
  private String time = "";
  @Override
  public Dialog onCreateDialog(Bundle savedInstanceState) {
    //新建日历类用于获取当前时间
    Calendar calendar = Calendar.getInstance();
    int hour = calendar.get(Calendar.HOUR_OF_DAY);
    int minute = calendar.get(Calendar.MINUTE);
    //返回TimePickerDialog对象
    //因为实现了OnTimeSetListener接口,所以第二个参数直接传入this
    return new TimePickerDialog(getActivity(), this, hour, minute, true);
  }

  //实现OnTimeSetListener的onTimeSet方法
  @Override
  public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
    //判断activity是否是DataCallBack的一个实例
    if(getActivity() instanceof DataCallBack){
      //将activity强转为DataCallBack
      DataCallBack dataCallBack = (DataCallBack) getActivity();
      time = time + hourOfDay + "点" + minute + "分";
      //调用activity的getData方法将数据传回activity显示
      dataCallBack.getData(time);
    }
  }

  public void setTime(String date){
    time += date;
  }

}

Activity的布局文件,只有一个TextView用于显示时间

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context="com.example.testdemo.TestActivityActivity">

  <TextView
    android:id="@+id/time_text"
    android:layout_centerInParent="true"
    android:text="点此选择时间"
    android:textSize="20sp"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

</RelativeLayout>

Activity文件:

//实现DataCallBack接口,实现与Fragment的通信
public class TestActivityActivity extends AppCompatActivity implements DataCallBack{

  TextView timeText;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_test2);
    timeText = (TextView) findViewById(R.id.time_text);
    //为timeText设置点击事件
    timeText.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        //实例化对象
        DatePickerFragment datePickerFragment = new DatePickerFragment();
        //调用show方法弹出对话框
        // 第一个参数为FragmentManager对象
        // 第二个为调用该方法的fragment的标签
        datePickerFragment.show(getFragmentManager(), "date_picker");
      }
    });
  }


  //实现DataCallBack的getData方法
  @Override
  public void getData(String data) {
    //data即为fragment调用该函数传回的日期时间
    timeText.setText(data);
  }
}

由于TimePickerFragment对话框是在DatePickerFragment类里面启动的,所以这样写只能日期和时间都选择,如果要单独选择日期或者时间,只需要重写onTimeSet()或者onDateSet()方法即可

兼容性问题

不同的android版本显示的效果不同,在android6.0效果很好,不过在一些低版本android(如4.0,笔者没有每个版本都测试)会出现调用两次回掉函数的情况,导致选择两次时间。解决的办法有很多,只要保证回调函数里面的逻辑只执行一次就可以。这里提供一种比较通用的方法。

重写TimePickerDialogDatePickerDialogonStop()方法

直接在Activity中使用的重写方法

final TimePickerDialog timePickerDialog = new TimePickerDialog(TestActivity.this, new TimePickerDialog.OnTimeSetListener() {
      //选择完时间后会调用该回调函数
      @Override
      public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
        time.append(" " + hourOfDay + ":" + minute);
        //设置TextView显示最终选择的时间
        timeText.setText(time);
      }
    }, hour, minute, true){
     // 重写onStop()
      @Override
      protected void onStop() {

      }
    };
    //实例化DatePickerDialog对象
    DatePickerDialog datePickerDialog = new DatePickerDialog(TestActivity.this, new DatePickerDialog.OnDateSetListener() {
      //选择完日期后会调用该回调函数
      @Override
      public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
        //因为monthOfYear会比实际月份少一月所以这边要加1
        time.append(year + "-" + (monthOfYear+1) + "-" + dayOfMonth);
        //选择完日期后弹出选择时间对话框
        timePickerDialog.show();
      }
    }, year, month, day){
      //重写onstop
      @Override
      protected void onStop() {
      }
    };

上面的写法看起来会比较乱,也可以另外新建一个类继承TimePickerDialog或者DatePickerDialog然后重写onStop()方法

通过FragmentDialog使用的重写方式

只需在onCreateDialog()方法里面重写即可,下面的代码会比较清晰

return new DatePickerDialog(getActivity(), this, year, month, day){
      // 重写onStop
      @Override
      protected void onStop() {
      }
    };
 return new TimePickerDialog(getActivity(), this, hour, minute, true){
      //重写onStop
      @Override
      protected void onStop() {
      }
    };

笔者水平有限,但是保证以上代码都是亲手实现过一遍的。如果有什么不足之处欢迎大家指出,以上就是本文的全部内容,希望对大家开发Android能有所帮助。

更多精彩内容其他人还在看

Android样式和主题之选择器的实例讲解

今天小编就为大家分享一篇关于Android样式和主题之选择器的实例讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
收藏 0 赞 0 分享

Android应用动态修改主题的方法示例

今天小编就为大家分享一篇关于Android应用动态修改主题的方法示例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
收藏 0 赞 0 分享

Flutter 网络请求框架封装详解

这篇文章主要介绍了Flutter 网络请求框架封装详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

Flutter倒计时/计时器的实现代码

这篇文章主要介绍了Flutter倒计时/计时器的实现代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

Android使用google breakpad捕获分析native cash

这篇文章主要介绍了Android使用google breakpad捕获分析native cash 的相关知识,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

详解Flutter WebView与JS互相调用简易指南

这篇文章主要介绍了详解Flutter WebView与JS互相调用简易指南,分为JS调用Flutter和Flutter调用JS,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

Android开发实现ListView和adapter配合显示图片和文字列表功能示例

这篇文章主要介绍了Android开发实现ListView和adapter配合显示图片和文字列表功能,涉及Android使用ListView结合adapter适配器实现图文显示功能相关的布局、解析、权限控制等操作技巧,需要的朋友可以参考下
收藏 0 赞 0 分享

Android文字基线Baseline算法的使用讲解

今天小编就为大家分享一篇关于Android文字基线Baseline算法的使用讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
收藏 0 赞 0 分享

Flutter自定义实现神奇动效的卡片切换视图的示例代码

这篇文章主要介绍了Flutter自定义实现神奇动效的卡片切换视图的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

Android实现自定义滑动刻度尺方法示例

这篇文章主要给大家介绍了关于Android实现自定义滑动刻度尺的相关资料,文中通过示例代码介绍的非常详细,对各位Android开发者们具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
收藏 0 赞 0 分享
查看更多