创建自定义 DatePicker 对话框 [英] Creating custom DatePicker dialog

查看:21
本文介绍了创建自定义 DatePicker 对话框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Requirement: When the user clicks on the TextView, a date picker should open up. The default date selected should be the date in the TextView. If the date is in the past, the DatePicker dialog's 'Set' button should be disabled. If the clickable TextView is empty, the default date in the DatePicker should be today's date.

推荐答案

这是一个我已经解决的方案,我在此分享以帮助 Xamarin 社区.代码不是很优化,仅供参考.

This is a scenario I've already solved and am sharing here in order to help the Xamarin community. The code isn't very optimized, just FYI.

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

So, what we exactly need in this scenario is access to the event that the user is changing dates on the DatePicker Dialog. This can only be done if you use a DatePicker inside your own Dialog for more control. In my opinion, you cannot get access to this event if you use the default DatePickerDialog. Thus, we create a dialog extending the DialogFragment class and then implement the DatePicker inside of it. When the user clicks the TextView, we use show the fragment. Let's begin:

这是主要活动:

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;
            }
        }

    }
}

Main.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 :

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 :

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>

这篇关于创建自定义 DatePicker 对话框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆