I followed the guidelines on google: TimePicker
I created a new class TimePickerFragment, but in my onTimeSet method I can't reach the gui element to update the picked time.
any ideas?
Related
Updated to describe the requested code; the updates are at the end.
I'm trying to do something that seems like it should be simple but the Android Life Cycle doesn't seem to be working as described. I expect this is a misunderstanding on my part, not a bug in Android!
I am new to Android and am just getting familiar with the Android Life Cycle after developing Java apps for Windows so I'm still struggling with a lot of new ideas, especially the Life Cycle.
I have nearly finished my first app, which is based on a RecyclerView. It shows a bunch of sales records (each representing one sale) of a small company. Users can click on a FloatingActionButton to report a new sale or click on edit or remove icons on the individual records to change the details of a sale or delete it entirely. Each of these things has its own activity. Also, there is a SettingsActivity to show settings.
One of the settings lets the user select from amongst three different date formats for displaying the date of the sale. When I back out of Settings (by hitting the back button), I want to see the visible rows using the newly-changed date format immediately but this is NOT happening. Up until now, I would just click on the buttons to take me to one of the other activities, then click the cancel button when I get there; on returning to my main activity, I would see the new date format.
I don't feel my user should have to go to that other activity; simply returning from Settings should change the dates immediately. I started looking at the Android Life Cycle. As I read the documentation, I should be overriding the onResume() method and issuing a notifyDataChanged() to the Adapter that controls the RecyclerView to get it to rebind the visible rows, using the new date format.
Unfortunately, that has no effect whatever that I can see. Here's my onResume:
#Override
protected void onResume() {
super.onResume();
mAdapter.notifyDataSetChanged();
}
Am I doing the notifyDataSetChanged() in the wrong method? If not, why doesn't it work? If it is the wrong method, which method should I be overriding?
Is there any particularly good text or video tutorial explaining the Life Cycle that I should be reading or viewing?
Updates
The date format is set in my SettingsActivity, which is the default one provided in the SettingsActivity template, tailored to meet my needs. All I've touched is the General settings. I replaced all of the ones from the template with six of my own settings. One is called Date format and defaults to YYYY-MM-DD; there are two other choices.
My main activity, which is the one that invokes SettingsActivity via a menu option, gets the value of the date format from the default SharedPreferences. This is because I don't want to look up the value of the Date format once for every row in the ArrayList but just once for all the rows in the ArrayList. I pass the value of the Date format to the Adapter via its constructor. The format gets used in OnBindViewHolder() to control the appearance of the date on the various sales records.
Define a set method to your adapter,
public class MyAdapter extends RecyclerView.Adapter<AdapterContactList.ViewHolder> {
private String dateFormat;
.....
public void setDateFormat(String dateFormat) {
this.dateFormat = dateFormat;
}
}
After user change the dateformat; set it to your adapter, then notify datas for change. That means, you need set new dateformat before notifyDataSetChanged method; because adapter doesn't know the new value.
#Override
protected void onResume() {
super.onResume();
String newDateFormat = getFromSharedPreferencesOrInstantly();
mAdapter.setDateFormat(newDateFormat);
mAdapter.notifyDataSetChanged();
}
I would like to highlight that I am looking for a Xamarin solution. I have found Java solutions, but I can't seem to convert them to Xamarin. I want to have the user set their birthday and then have the app calculate their age, and display it as text. I have everything functioning. All I am looking to do is change the text on the "ok" button to "Calculate age." I am able to change the text, but the button doesn't grab the date from the picker then. This is how I create my datepicker:
DatePickerDialog setDate = new DatePickerDialog(this, onDateSet, date.Year, date.Month-1, date.Day);
then I use this method to change the text
setDate.SetButton("calculate age", EventHandler<DialogClickEventArgs>)
I have created an EventHandler called Age use for the second argument. What code do I put in the EventHandler to make the button function like the "ok" button? if I set handler:null the method works, I can also get the method to do other things, change text in textbox for a example. Any solution is welcomed.
Wow. No love for Xamarin? I discovered the solution was much simpler. Following from what I learned here: Change DatePickerDialog's button texts. I began throwing darts into the code and this is what stuck. Where I set handler to null I simply set listener to the dialog object like so. setDate.SetButton ("calculate age", listener:setDate);
I'm using a CalendarView directly, not a DatePicker, b/c its being used as a drop-down/pop-up style dialog where space is factor ( the user clicks a button located to the right of date field, and the CalendarView drops down, appearing directly below the field, aligned/anchored to the button).
There are two show-stopping issues I've ran into, and spent an entire 10 hour day debugging with no resolve.
Issue #1 - Weeks Missing
Weeks appear to missing, and depending on the date, sometimes the week missing will correspond to the "default"/current date (the date the displayed record contains that was loaded from the DB), and so when I display the CalendarView, and call setDate() to auto-select it, no date will appear to be selected (although the CalendarView will be centered around the missing week).
The way I've been fixing this is to manually scroll down, and then back up a few months, and the refresh usually fixes the display. However, I haven't found a way to automate this scrolling, which could be a potential work around. I tried calling setDate() in succession to do this, but it seems to only work on the first call, which brings me to my next issue.
Issue #2 - setDate() Auto-Scrolling Not Working
It seems that only the first call to setDate() will cause the CalendarView to be centered around the corresponding date. If I choose a new date (and store it in private member) and dismiss the popup, and then bring it back up with another dropdown-button click, which will now call setDate() with this new date, then the CalendarView will be centered around the old/previous date, even though the new date is actually hilited (which can be confirmed my manually scrolling down to it).
I can attach code if required, but before spending the time to do so, I just wanted to see if this is a well known issue.
Thank you.
This is just a work-around (also, I've been working in Monodroid/C#, not raw Android)
By first calling SetDate() with a value for the last day of the month previous to the desired display date, and then calling it with the desired date, it seems to work consistently as expected (make sure this date falls between the Max/Min dates of the CalendarView).
However, the second call needs to be posted as a runnable to the UI thread.
Here is some code (note the boolean flags to SetDate, for centering and scroll-animation, neither of which work, hence this work-around):
View view = _inflater.Inflate( Resource.Layout.CalendarViewPicker, null );
CalendarView cvPicker = view.FindViewById<Android.Widget.CalendarView>( Resource.Id.cv_picker );
DateTime lastDay = new DateTime(_date.Year, _date.Month, 1).AddDays(-1);
long lastDayTicks = Ticks( lastDay.Date );
cvPicker.SetDate( lastDayTicks, true, true );
cvPicker.Post( () => {cvPicker.SetDate(Ticks(_date.Date),true,true)} );
Passing _date.Date to Ticks() passes a DateTime with a Time of 12:00am (basically "zeros out" time element), as opposed to passing just _date, which is also a DateTime. Also, a conversion function is needed, since I'm using C#/.NET, to convert the tick-offset
private long Ticks( DateTime date )
{
DateTime _1970 = (new DateTime(1970, 1, 1)).AddDays(-1);
return (date.Ticks - _1970.Ticks) / 10000;
}
Resource.Layout.CalendarViewPicker.axml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="#dimen/calendar_view_width"
android:layout_height="#dimen/calendar_view_height"
android:background="#FF666666">
<Button
android:id="#+id/btn_picker_exit"
android:layout_width="60dp"
android:layout_height="36dp"
android:layout_alignParentTop="true"
android:background="#drawable/cv_button_background"
android:gravity="center"
android:textColor="#FFFFFFFF"
android:textSize="20sp"
android:text="+"/>
<CalendarView
android:id="#+id/cv_picker"
android:layout_width="#dimen/calendar_view_width"
android:layout_height="#dimen/calendar_view_height"
android:shownWeekCount="6"/>
<RelativeLayout/>
My reasoning for the first call to SetDate() with the last day of the previous month, was b/c many times the calendar would popup with the second week of a given month showing as the first visible week, and when scrolling up to see the first week, I would find it missing. So, I figured setting the date with the last day of the previous month might force the first week (ie, the problematic week) to show.
Now with the first week showing, I call SetDate again, but it only works when posted, b/c when posting a runnable to the UI, the event is scheduled to occur after the associated view is rendered. If 2 SetDate()'s are called consecutively (neither in a runnable), say in OnCreate(), then the effects take place before the view is rendered, and so only the second call would take effect, overwriting the first (and therefore loosing the effect of forcing the first week to show).
These two calls also fix the centering/auto-scrolling issue, which is nice too.
I am porting one of my iOS apps over to android, and one of the layouts uses the UIDatePicker with the mode UIDatePickerModeCountDownTimer. I have searched and searched and searched for something even close in android, and the only thing I have come across is the TimePicker widget which only seems to do time of day.
Does something like UIDatePickerModeCountDownTimer exist in android, or do I have to fenagle my own solution for entering this type of time.
There is no one stop shop that includes a date picker and a time picker, both are seperate
so basically you need a date field that shows a DatePickerDialog and a time field that show a TimePickerDialog when clicked
As far as I am aware you will either need a 3rd party library or you will need to create a custom version of the TimePicker.
EDIT :
Basically i've done something similar like your requirement, i have a time picker dialog in dialog fragment, without am/pm indicator. You only have to set the DateFormat to 24 hour format in onCreateDialog method. Something similar like this :
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the current time as the default values for the picker
int hour = 0;
int minute = 0;
// Create a new instance of TimePickerDialog without am/pm and return it
return new TimePickerDialog(getActivity(), this, hour, minute,
DateFormat.is24HourFormat(getActivity()));
}
I hope this answer help you :)
This question is about TimePicker behavior in Android.
To get the value of the Hour and the Minute I use getCurrentHour() and getCurrentMinute().
At first I found out that changes made by the user using the phone keyboard where not registered so calling getCurrentHour() or getCurrentMinute() did not show the values changed in the texboxes inside the widget.
This was quickly solved using setAddStatesFromChildren(true); With this I get those changes.
Now, my problem is that those changes are only registered if timepicker looses focus.
So, getting the value from timepicker inside a button gets a wrong value because it hasn't loose focus.
Any help?
What I need is: Can I force a timepicker to loose focus and get the real written value in text boxes?
I solved it and I write it here for someone who needs it.
Thanks to "Tarun Maheshwari" I found what I needed:
On onCreate do something like this:
MyTimerPicker.setAddStatesFromChildren(true);
On the onClick method, when getting the values, do this:
MyTimerPicker.clearFocus();
int iHour = MyTimerPicker.getCurrentHour();
int iMinute = MyTimerPicker.getCurrentMinute();
Call clearFocus() on the timepicker view after you get onTimeChanged callback.