calendar - Creating custom DatePicker dialog -
requirement: when user clicks on textview, date picker should open up. default date selected should date in textview. if date in past, datepicker dialog's 'set' button should disabled. if clickable textview empty, default date in datepicker should today's date.
this scenario i've solved , sharing here in order xamarin community. code isn't optimized, fyi.
so, need in scenario access event user changing dates on datepicker dialog. can done if use datepicker inside own dialog more control. in opinion, cannot access event if use default datepickerdialog. thus, create dialog extending dialogfragment class , implement datepicker inside of it. when user clicks textview, use show fragment. let's begin:
here's 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 "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 communication fragment public string getduedate() { return duedate; } //used communication fragment public void setduedate(datetime date) { //additional check date isn't set in 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 instance of mainactivity mactivity = (mainactivity) this.activity; //get set due date duedate = mactivity.getduedate(); //get instance of calendar calendar today = calendar.instance; //update 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 dialog layout var view = inflater.inflate(resource.layout.mdialoglayout, container, false); //finding 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 make default datepicker picker.calendarviewshown = false; //checking see if current date in past, if yes, disable 'set' button if ((datetime.parse(duedate) < datetime.now)) { set.enabled = false; } //initate picker current due date or today's date picker.init(getdefaultyear(), getdefaultmonth(), getdefaultdayofmonth(), new ondatechangedlistener((picker1, year, month, day) => { //getting datepicker value in string tempstring = (month + 1) + "/" + day + "/" + year; //parsing value variable selectedduedate = (datetime.parse(tempstring).date); //setting mdatepicker dialog's title dialog.settitle(getdatedetails(selectedduedate)); //enable/disalbe 'set' button depending on condition if (selectedduedate >= datetime.now.date) set.enabled = true; else set.enabled = false; })); //setting dialog title first time when opens dialog.settitle(getdatedetails(datetime.parse(duedate))); //click function cancel button cancel.click += delegate{dismiss();}; //click function 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 set due date in 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 class , interface implementation create , init 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>
Comments
Post a Comment