文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2022-06-06 07:51

关注

前言

由于大部分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,笔者没有每个版本都测试)会出现调用两次回掉函数的情况,导致选择两次时间。解决的办法有很多,只要保证回调函数里面的逻辑只执行一次就可以。这里提供一种比较通用的方法。

重写

TimePickerDialog
DatePickerDialog
onStop()
方法

直接在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时间选择器、日期选择器实现代码Android中TimePicker与DatePicker时间日期选择组件的使用实例Android之日期及时间选择对话框用法实例分析解析android中系统日期时间的获取android计时器,时间计算器的实现方法android获取时间差的方法android 默认时间格式修改方法Android调用系统时间格式显示时间信息


阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯