【问题标题】:Creating custom DatePicker dialog创建自定义 DatePicker 对话框
【发布时间】:2015-03-20 18:33:14
【问题描述】:

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

【问题讨论】:

    标签: datepicker calendar xamarin xamarin.android android-datepicker


    【解决方案1】:

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

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

    这是 MainActivity:

    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:

    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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-01
      • 2022-01-24
      • 1970-01-01
      • 2010-10-21
      • 2011-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多