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

查看:197
本文介绍了创建自定义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社区。代码不是非常优化,只是FYI。

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对话框中更改日期的事件。这只能在您自己的对话框中使用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:

这是MainActivity:

Here's the 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:

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: p>

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天全站免登陆