创建自定义 DatePicker 对话框

2024-01-19

要求:当用户单击 TextView 时,应打开一个日期选择器。选择的默认日期应该是 TextView 中的日期。如果日期是过去的日期,则应禁用 DatePicker 对话框的“设置”按钮。如果可点击的 TextView 为空,则 DatePicker 中的默认日期应该是今天的日期。


这是我已经解决的场景,为了帮助 Xamarin 社区,我在这里分享。代码不是很优化,仅供参考。

因此,在这种情况下我们真正需要的是访问用户在 DatePicker 对话框上更改日期的事件。仅当您在自己的对话框中使用 DatePicker 以获得更多控制时才能完成此操作。在我看来,如果您使用默认的 DatePickerDialog,则无法访问此事件。因此,我们创建一个扩展 DialogFragment 类的对话框,然后在其中实现 DatePicker。当用户单击 TextView 时,我们使用显示片段。让我们开始:

这是主要活动:

using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using Java.Util;
using Java.Text;


namespace DatePickerTest
{
    [Activity(Label = "DatePickerTest", MainLauncher = true, Icon = "@drawable/icon", Theme = "@android:style/Theme.Holo.Light")]
    public class MainActivity : Activity
    {
        private string dueDate;

        private TextView dateLabel;
        private DateTime date;

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.Main);

            dateLabel = (TextView)FindViewById(Resource.Id.dateLabel);

            dueDate = dateLabel.Text;

            dateLabel.Click += delegate { ShowDialog(); };

        }

        public void ShowDialog()
        {
            var transaction = FragmentManager.BeginTransaction();
            var dialogFragment = new mDialogFragment();
            dialogFragment.Show(transaction, "dialog_fragment");
        }

        //Used for communication with the fragment
        public string GetDueDate()
        {
            return dueDate;
        }

        //Used for communication with the fragment
        public void SetDueDate(DateTime date)
        {
         //Additional check so that date isn't set in the past
            if (date < DateTime.Now.Date)
                Toast.MakeText(this, "Something went wrong! Please try again", ToastLength.Long).Show();
            else
            {
                SimpleDateFormat MdyFormat = new SimpleDateFormat("MM/dd/yyyy");
                dueDate = MdyFormat.Format(Date.Parse(date.ToString()));
                dateLabel.Text = dueDate;
            }
        }

    }
}

主要.axml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <Button
        android:id="@+id/MyButton"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/Hello" />
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:background="#FAFAFA"
        android:layout_height="wrap_content">
        <TextView
            android:id="@+id/dueDateLabel"
            android:layout_height="45dp"
            android:layout_width="wrap_content"
            android:text="Due Date:"
            android:padding="15dp"
            android:textColor="#2E2E2E" />
        <TextView
            android:id="@+id/dateLabel"
            android:layout_height="45dp"
            android:layout_width="fill_parent"
            android:hint="Some Date"
            android:textColor="#2E2E2E"
            android:text="03/16/2015" />
    </LinearLayout>
</LinearLayout>

MDialogFragment.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Util;
using Android.Views;
using Android.Widget;
using Java.Util;
using Java.Text;

namespace DatePickerTest
{
    public class mDialogFragment : DialogFragment
    {
        DatePicker picker;
        private MainActivity MActivity;
        private int Year, Month, Day;
        private string DueDate;
        private DateTime SelectedDueDate;
        private string tempString = "";

        public override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);

            //Get the instance of the MainActivity
            MActivity = (MainActivity) this.Activity;

            //Get the currently set due date
            DueDate = MActivity.GetDueDate();

            //Get instance of the Calendar
            Calendar Today = Calendar.Instance;

            //Update the class variables
            Year = Today.Get(Calendar.Year);
            Month = Today.Get(Calendar.Month);
            Day = Today.Get(Calendar.Date);
        }

        public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            //Inflating the dialog layout
            var view = inflater.Inflate(Resource.Layout.MDialogLayout, container, false);
            //Finding all the views in it:
            var cancel = (Button)view.FindViewById(Resource.Id.cancel);
            var set = (Button)view.FindViewById(Resource.Id.set);
            picker = (DatePicker)view.FindViewById(Resource.Id.pickerdate);

            //DatePicker flag to make it look like the default DatePicker
            picker.CalendarViewShown = false;

            //Checking to see if current date is in the past, if YES, disable the 'Set' button
            if ((DateTime.Parse(DueDate) < DateTime.Now)) { set.Enabled = false; }

            //Initate the picker with the current due date OR today's date
            picker.Init(GetDefaultYear(), GetDefaultMonth(), GetDefaultDayOfMonth(), new onDateChangedListener((picker1, year, month, day) =>
            {
                //Getting the DatePicker value in a string
                tempString = (month + 1) + "/" + day + "/" + year;

                //Parsing the value into a variable
                SelectedDueDate = (DateTime.Parse(tempString).Date);

                //Setting the MDatePicker dialog's Title
                Dialog.SetTitle(GetDateDetails(SelectedDueDate));

                //Enable/Disalbe 'Set' button depending on the condition
                if (SelectedDueDate >= DateTime.Now.Date)
                    set.Enabled = true;
                else
                    set.Enabled = false;

            }));

            //Setting Dialog Title for the first time when it opens
            Dialog.SetTitle(GetDateDetails(DateTime.Parse(DueDate)));

            //Click function for Cancel button
            cancel.Click += delegate{Dismiss();};

            //Click function for Set button
            set.Click += (object sender, EventArgs e) =>
            {
                SetSelectedDueDate(sender, e);
            };
            return view;
        }

        private string GetDateDetails(DateTime date)
        {
            string DateDetails;
            Calendar cal = Calendar.Instance;
            SimpleDateFormat DayOfWeekFormat = new SimpleDateFormat("EEE");
            SimpleDateFormat MonthFormat = new SimpleDateFormat("MMM");

            DateDetails = DayOfWeekFormat.Format(Date.Parse(date.ToString())) + ", " + date.Day + " " + MonthFormat.Format(Date.Parse(date.ToString())) + " " + date.Year;

            return DateDetails;
        }

        private void SetSelectedDueDate(object sender, EventArgs e)
        {
            MActivity.SetDueDate(SelectedDueDate);
            Dismiss();
        }

        private int GetDefaultMonth()
        {
            //The currently set due date is in the format "MM/DD/YYYY"
            if(MActivity.GetDueDate()==null || MActivity.GetDueDate() == "")
                return Month;

            return Convert.ToInt32(MActivity.GetDueDate().Substring(0, 2)) - 1;


        }

        private int GetDefaultDayOfMonth()
        {
            if (MActivity.GetDueDate() == null || MActivity.GetDueDate() == "")
                return Day;
            return Convert.ToInt32(MActivity.GetDueDate().Substring(3, 2)); 
        }

        private int GetDefaultYear()
        {
            if (MActivity.GetDueDate() == null || MActivity.GetDueDate() == "")
                return Year;
            return Convert.ToInt32(MActivity.GetDueDate().Substring(6, 4));
        }
    }

    //We need this class and interface implementation to create and Init the DatePicker
    class onDateChangedListener : Java.Lang.Object, DatePicker.IOnDateChangedListener
    {

        Action<DatePicker, int, int, int> callback;

        public onDateChangedListener(Action<DatePicker, int, int, int> callback)
        {
            this.callback = callback;
        }

        public void OnDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth)
        {
            callback(view, year, monthOfYear, dayOfMonth);
        }
    }
}

MDialogLayout.axml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">

    <DatePicker
        android:id="@+id/pickerdate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal" />
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">
        <Button
            android:id="@+id/cancel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Cancel"
            android:layout_weight="1"
            style="?android:attr/buttonBarButtonStyle" />
        <Button
            android:id="@+id/set"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="SET"
            android:layout_weight="1"
            style="?android:attr/buttonBarButtonStyle"
            android:paddingTop="1dp" />
    </LinearLayout>
</LinearLayout>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

创建自定义 DatePicker 对话框 的相关文章

随机推荐

  • 致命错误:内存不足,但我有足够的内存(PHP)

    由于我的问题越来越长 我决定重写整个问题 使其更好 更短 我在 8GB 内存的专用服务器上运行我的网站 我完全意识到我需要提高 php ini 设置的内存限制 我已将其从 128M 设置为 256M 然后设置为 1 但问题仍然在于坚持 致命
  • Java Pattern.matcher() 在匹配包含 \n 的行时冻结

    我遇到了一个我觉得很有趣的问题 我主要通过正则表达式对文本文件进行一些基本解析 并且在匹配此行时它总是冻结 ftrect 0 7031 57 0313 9 8561 55 5313 FREIGABE nQ09 SV01 没有抛出异常 程序只
  • mysql(几乎)完成审计

    我正在寻找一种为我的表制作简单事件日志的方法 我有几个表可以由不同的用户更改 我想跟踪 who made the change when what was before update what is the new value which
  • 将 HTTP 请求映射到 HTTP 响应

    如果我向同一服务器发出多个 HTTP Get 请求 并且每个请求都获得 HTTP 200 OK 响应 我如何使用 Wireshark 判断哪个请求映射到哪个响应 目前看起来好像发出了一个 http 请求 并且很快收到了下一个 HTTP 20
  • PDO 函数 setFetchMode

    你好 我试图用 PDO 来实现函数 但出现错误 PDO 新手 这是我的代码 function mail id mail global host dbname user pass DBH new PDO mysql host host dbn
  • 通过 Bower 安装 jQuery-Mobile

    在我的项目中 我想通过 Bower 使用 jquery mobile 在我可以使用它之前我必须运行npm install and grunt随后在bower components jquery mobile在我可以使用缩小版之前 js an
  • 解析显式数组

    我正在尝试解析来自服务器的此类响应 1 a b 2 000000 1 2 3 1 2 3 x y z 1 2 3 1 2 3 除了为这种类型的消息编写我自己的 hack ish 解析器之外 还有一种我不知道的标准方法来解释它吗 您的输入是J
  • JQuery UI,单页上多个日期选择器

    我正在为房地产创建一个 PHP 网站 我是 jQuery 和 jQuery UI 的新手 但似乎无法在其他地方找到答案 请看这个屏幕截图 全尺寸 https i stack imgur com b3yQX png 对于每个 已收到 和 到期
  • Angular UI Router:abstract:true不会显示页面

    我正在尝试使用嵌套导航来围绕 Angular UI Router 进行思考 我的应用程序有多个页面 我已经设置了 StateProvider 并且页面之间的基本路由可以正常工作 但是 我现在尝试在这些页面之一中实现选项卡式视图 我就是无法让
  • Jquery序列化和serializeArray不适用于谷歌浏览器

    我有以下 html fieldset fieldset
  • 如何在 VBA (Excel) 中获取以毫秒为单位的 DateDiff-Value?

    我需要计算两个时间戳之间的差异 以毫秒为单位 不幸的是 VBA 的 DateDiff 函数不提供这种精度 有什么解决方法吗 您可以使用描述的方法here http www tek tips com faqs cfm fid 2292如下 创
  • 如何在集群中为一个节点和所有节点运行计划方法?

    我有一个在集群中运行的 Glassfish 3 1 2 和一个 EJB 3 1 应用程序 我的应用程序中需要两种预定方 法 一种每天只运行一次 在单个节点上 以及其他在所有节点上运行的类型 每 1 2 分钟 它们不需要运行同步方式 要求只是
  • 如何递归地将项目添加到列表中?

    目前 我正在解决一个问题 我得到一个列表 其元素可能包含其他列表 列表的列表或整数 例如 我可能会收到 1 2 3 4 5 6 7 9 我的目标是解析数组并附加仅整数到一个新列表 这是我到目前为止所做的 def fun a if a ret
  • Django Admin:列表中的分组数据

    我可以在 Django Admin 中显示分组结果吗 默认情况下 它们显示所有行 我想根据某些字段对这些行进行分组并显示它 像 GROUP BY username 之类的东西 我尝试过搜索但没有成功 使用怎么样list filter my
  • IMFMediSource 不支持 IKsPropertySet 接口

    我正在将基于 Direct Show 相机的 SDK 移植到 MFT 在我的旧代码中 我有 KSProxy 接口 如 IksTopolgy IKsControl 和 IKsProperty IksTopolgy IKsControl 用于枚
  • 如何在 JavaScript 中将值从一个 html 页面传递到另一个页面?

    我知道这个问题问了很多次 但我的问题有所不同 我有 3 个 html 页面 例如apply html personal info html resume info html 在 apply html 页面中 我使用一个 LinkedIn 按
  • 从 android init.rc 执行静态程序

    我想在以下位置启动一个自定义程序init过程 我静态编译了这个程序 它可以在我启动的 android stock ROM 中正常运行 来自安卓init rc我读到的文档exec命令是我需要的 顺便说一句 我能看到的都是dmesg我的程序退出
  • 如何在Azure功能上安装apt-get包

    在 Linux 消费计划上运行 python Azure 函数 我已经能够使用 VS Code 成功将该函数部署到 Azure requirements txt 中的所有包都可以顺利安装 但现在我需要安装tesseract 它只能通过apt
  • 是否可以对特定于浏览器的 CSS 使用 mixin

    我正在寻找一种使用 mixin 进行特定于浏览器的 CSS hack 的解决方案 我正在使用 JavaScript 在 HTML 类中添加浏览器标签 喜欢 ie ie7 ie8 ie9 我想使用 mixin 像 box test margi
  • 创建自定义 DatePicker 对话框

    要求 当用户单击 TextView 时 应打开一个日期选择器 选择的默认日期应该是 TextView 中的日期 如果日期是过去的日期 则应禁用 DatePicker 对话框的 设置 按钮 如果可点击的 TextView 为空 则 DateP