From e73dec96184c984bf57ebefa8d4ea91c9ed71f9b Mon Sep 17 00:00:00 2001 From: Grzegorz Orczykowski Date: Mon, 27 Mar 2017 11:23:50 +0200 Subject: [PATCH 01/25] TimeWidget: added new button and TextView --- .../collect/android/widgets/TimeWidget.java | 52 +++++++++++++++++-- collect_app/src/main/res/values/strings.xml | 1 + 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java index d1cdc096bf0..89899a726ce 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java @@ -16,14 +16,21 @@ import android.content.Context; import android.os.Build; +import android.util.TypedValue; import android.view.Gravity; +import android.view.View; import android.view.inputmethod.InputMethodManager; +import android.widget.Button; +import android.widget.LinearLayout; +import android.widget.TableLayout; +import android.widget.TextView; import android.widget.TimePicker; import org.javarosa.core.model.data.IAnswerData; import org.javarosa.core.model.data.TimeData; import org.javarosa.form.api.FormEntryPrompt; import org.joda.time.DateTime; +import org.odk.collect.android.R; import org.odk.collect.android.application.Collect; import java.util.Date; @@ -37,6 +44,8 @@ public class TimeWidget extends QuestionWidget { private TimePicker mTimePicker; + private Button mTimeButton; + private TextView mTimeTextView; public TimeWidget(Context context, final FormEntryPrompt prompt) { super(context, prompt); @@ -84,8 +93,10 @@ public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { }); setGravity(Gravity.LEFT); - addAnswerView(mTimePicker); + createTimeButton(); + createTimeTextView(); + addViews(); } @@ -136,14 +147,49 @@ public void setFocus(Context context) { @Override public void setOnLongClickListener(OnLongClickListener l) { - mTimePicker.setOnLongClickListener(l); + mTimeButton.setOnLongClickListener(l); + mTimeTextView.setOnLongClickListener(l); } @Override public void cancelLongPress() { super.cancelLongPress(); - mTimePicker.cancelLongPress(); + mTimeButton.cancelLongPress(); + mTimeTextView.cancelLongPress(); } + private void createTimeButton() { + TableLayout.LayoutParams params = new TableLayout.LayoutParams(); + params.setMargins(7, 5, 7, 5); + + mTimeButton = new Button(getContext()); + mTimeButton.setId(QuestionWidget.newUniqueId()); + mTimeButton.setText(R.string.select_time); + mTimeButton.setPadding(20, 20, 20, 20); + mTimeButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mAnswerFontsize); + mTimeButton.setLayoutParams(params); + mTimeButton.setEnabled(!mPrompt.isReadOnly()); + + mTimeButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + } + }); + } + + private void createTimeTextView() { + mTimeTextView = new TextView(getContext()); + mTimeTextView.setId(QuestionWidget.newUniqueId()); + mTimeTextView.setPadding(20, 20, 20, 20); + mTimeTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mAnswerFontsize); + } + + private void addViews() { + LinearLayout linearLayout = new LinearLayout(getContext()); + linearLayout.setOrientation(LinearLayout.VERTICAL); + linearLayout.addView(mTimeButton); + linearLayout.addView(mTimeTextView); + addAnswerView(linearLayout); + } } diff --git a/collect_app/src/main/res/values/strings.xml b/collect_app/src/main/res/values/strings.xml index 1a409583c03..3989c426d9c 100644 --- a/collect_app/src/main/res/values/strings.xml +++ b/collect_app/src/main/res/values/strings.xml @@ -496,4 +496,5 @@ Sort the list ODK Collect needs access to your Google account to get blank forms and submit filled forms. Filter the list +Select time \ No newline at end of file From 21b28d1ecf3232b98d1b5e0c45bec6d0edf3e9ca Mon Sep 17 00:00:00 2001 From: Grzegorz Orczykowski Date: Mon, 27 Mar 2017 11:27:52 +0200 Subject: [PATCH 02/25] TimeWidget: added setTime() method --- .../collect/android/widgets/TimeWidget.java | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java index 89899a726ce..4c3cd71747f 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java @@ -47,6 +47,9 @@ public class TimeWidget extends QuestionWidget { private Button mTimeButton; private TextView mTimeTextView; + private int mHourOfDay; + private int mMinuteOfHour; + public TimeWidget(Context context, final FormEntryPrompt prompt) { super(context, prompt); @@ -105,14 +108,8 @@ public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { */ @Override public void clearAnswer() { - DateTime ldt = new DateTime(); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - mTimePicker.setHour(ldt.getHourOfDay()); - mTimePicker.setMinute(ldt.getMinuteOfHour()); - } else { - mTimePicker.setCurrentHour(ldt.getHourOfDay()); - mTimePicker.setCurrentMinute(ldt.getMinuteOfHour()); - } + DateTime dt = new DateTime(); + setTime(dt.getHourOfDay(), dt.getMinuteOfHour()); } @@ -192,4 +189,14 @@ private void addViews() { linearLayout.addView(mTimeTextView); addAnswerView(linearLayout); } + + private void setTime(int hourOfDay, int minuteOfHour) { + mHourOfDay = hourOfDay; + mMinuteOfHour = minuteOfHour; + + String hour = mHourOfDay < 10 ? "0" + mHourOfDay : "" + mHourOfDay; + String minute = mMinuteOfHour < 10 ? "0" + mMinuteOfHour : "" + mMinuteOfHour; + + mTimeTextView.setText(hour + ":" + minute); + } } From 7a3ac30a048799c17b899f80f6346d5b69066390 Mon Sep 17 00:00:00 2001 From: Grzegorz Orczykowski Date: Mon, 27 Mar 2017 11:31:29 +0200 Subject: [PATCH 03/25] TimeWidget: added TimePickerDialog --- .../collect/android/widgets/TimeWidget.java | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java index 4c3cd71747f..693debc0de5 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java @@ -14,8 +14,10 @@ package org.odk.collect.android.widgets; +import android.app.TimePickerDialog; import android.content.Context; import android.os.Build; +import android.text.format.DateFormat; import android.util.TypedValue; import android.view.Gravity; import android.view.View; @@ -41,7 +43,7 @@ * @author Carl Hartung (carlhartung@gmail.com) */ public class TimeWidget extends QuestionWidget { - + private TimePickerDialog mTimePickerDialog; private TimePicker mTimePicker; private Button mTimeButton; @@ -99,6 +101,7 @@ public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { createTimeButton(); createTimeTextView(); + createTimePickerDialog(); addViews(); } @@ -110,6 +113,7 @@ public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { public void clearAnswer() { DateTime dt = new DateTime(); setTime(dt.getHourOfDay(), dt.getMinuteOfHour()); + mTimePickerDialog.updateTime(mHourOfDay, mMinuteOfHour); } @@ -171,6 +175,8 @@ private void createTimeButton() { mTimeButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { + mTimePickerDialog.updateTime(mHourOfDay, mMinuteOfHour); + mTimePickerDialog.show(); } }); } @@ -199,4 +205,25 @@ private void setTime(int hourOfDay, int minuteOfHour) { mTimeTextView.setText(hour + ":" + minute); } + + private void createTimePickerDialog() { + mTimePickerDialog = new TimePickerDialog(getContext(), + new TimePickerDialog.OnTimeSetListener() { + @Override + public void onTimeSet(TimePicker view, int hourOfDay, int minuteOfHour) { + setTime(hourOfDay, minuteOfHour); + } + }, 0, 0, DateFormat.is24HourFormat(getContext())); + + // If there's an answer, use it. + if (mPrompt.getAnswerValue() != null) { + // create a new date time from date object using default time zone + DateTime dt = new DateTime(((Date) mPrompt.getAnswerValue().getValue()).getTime()); + setTime(dt.getHourOfDay(), dt.getMinuteOfHour()); + mTimePickerDialog.updateTime(mHourOfDay, mMinuteOfHour); + } else { + // create time widget with current time as of right now + clearAnswer(); + } + } } From 8ba95ee7724f3a4fdfa843c7722b418922dadefc Mon Sep 17 00:00:00 2001 From: Grzegorz Orczykowski Date: Mon, 27 Mar 2017 11:33:40 +0200 Subject: [PATCH 04/25] TimeWidget: removed unnecessary code --- .../collect/android/widgets/TimeWidget.java | 63 +------------------ 1 file changed, 1 insertion(+), 62 deletions(-) diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java index 693debc0de5..d42c66a5c31 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java @@ -16,7 +16,6 @@ import android.app.TimePickerDialog; import android.content.Context; -import android.os.Build; import android.text.format.DateFormat; import android.util.TypedValue; import android.view.Gravity; @@ -33,7 +32,6 @@ import org.javarosa.form.api.FormEntryPrompt; import org.joda.time.DateTime; import org.odk.collect.android.R; -import org.odk.collect.android.application.Collect; import java.util.Date; @@ -44,7 +42,6 @@ */ public class TimeWidget extends QuestionWidget { private TimePickerDialog mTimePickerDialog; - private TimePicker mTimePicker; private Button mTimeButton; private TextView mTimeTextView; @@ -55,48 +52,6 @@ public class TimeWidget extends QuestionWidget { public TimeWidget(Context context, final FormEntryPrompt prompt) { super(context, prompt); - mTimePicker = new TimePicker(getContext()); - mTimePicker.setId(QuestionWidget.newUniqueId()); - mTimePicker.setFocusable(!prompt.isReadOnly()); - mTimePicker.setEnabled(!prompt.isReadOnly()); - - String clockType = - android.provider.Settings.System.getString(context.getContentResolver(), - android.provider.Settings.System.TIME_12_24); - if (clockType == null || clockType.equalsIgnoreCase("24")) { - mTimePicker.setIs24HourView(true); - } - - // If there's an answer, use it. - if (prompt.getAnswerValue() != null) { - - // create a new date time from date object using default time zone - DateTime ldt = - new DateTime( - ((Date) prompt.getAnswerValue().getValue()).getTime()); - System.out.println("retrieving:" + ldt); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - mTimePicker.setHour(ldt.getHourOfDay()); - mTimePicker.setMinute(ldt.getMinuteOfHour()); - } else { - mTimePicker.setCurrentHour(ldt.getHourOfDay()); - mTimePicker.setCurrentMinute(ldt.getMinuteOfHour()); - } - - } else { - // create time widget with current time as of right now - clearAnswer(); - } - - mTimePicker.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() { - @Override - public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { - Collect.getInstance().getActivityLogger().logInstanceAction(TimeWidget.this, - "onTimeChanged", - String.format("%1$02d:%2$02d", hourOfDay, minute), mPrompt.getIndex()); - } - }); - setGravity(Gravity.LEFT); createTimeButton(); @@ -105,7 +60,6 @@ public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { addViews(); } - /** * Resets time to today. */ @@ -116,27 +70,14 @@ public void clearAnswer() { mTimePickerDialog.updateTime(mHourOfDay, mMinuteOfHour); } - @Override public IAnswerData getAnswer() { clearFocus(); // use picker time, convert to today's date, store as utc - DateTime ldt; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - ldt = (new DateTime()).withTime(mTimePicker.getHour(), - mTimePicker.getMinute(), - 0, 0); - } else { - ldt = (new DateTime()).withTime(mTimePicker.getCurrentHour(), - mTimePicker.getCurrentMinute(), - 0, 0); - } - //DateTime utc = ldt.withZone(DateTimeZone.forID("UTC")); - System.out.println("storing:" + ldt); + DateTime ldt = (new DateTime()).withTime(mHourOfDay, mMinuteOfHour, 0, 0); return new TimeData(ldt.toDate()); } - @Override public void setFocus(Context context) { // Hide the soft keyboard if it's showing. @@ -145,14 +86,12 @@ public void setFocus(Context context) { inputManager.hideSoftInputFromWindow(this.getWindowToken(), 0); } - @Override public void setOnLongClickListener(OnLongClickListener l) { mTimeButton.setOnLongClickListener(l); mTimeTextView.setOnLongClickListener(l); } - @Override public void cancelLongPress() { super.cancelLongPress(); From 4282264afebaa5d44ba12a3d8a026dfbb4f80b7b Mon Sep 17 00:00:00 2001 From: Grzegorz Orczykowski Date: Mon, 27 Mar 2017 12:15:51 +0200 Subject: [PATCH 05/25] DateWidget: added new button and TextView --- .../collect/android/widgets/DateWidget.java | 52 ++++++++++++++++++- collect_app/src/main/res/values/strings.xml | 1 + 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java index e3685117482..a2e7d811a24 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java @@ -18,19 +18,24 @@ import android.content.Context; import android.content.res.Resources; import android.os.Build; +import android.util.TypedValue; import android.view.Gravity; import android.view.View; import android.view.inputmethod.InputMethodManager; +import android.widget.Button; import android.widget.CalendarView; import android.widget.DatePicker; import android.widget.HorizontalScrollView; import android.widget.LinearLayout; +import android.widget.TableLayout; +import android.widget.TextView; import org.javarosa.core.model.data.DateData; import org.javarosa.core.model.data.IAnswerData; import org.javarosa.form.api.FormEntryPrompt; import org.joda.time.DateTime; import org.joda.time.LocalDateTime; +import org.odk.collect.android.R; import org.odk.collect.android.application.Collect; import org.odk.collect.android.utilities.DateWidgetUtils; @@ -46,6 +51,9 @@ */ public class DateWidget extends QuestionWidget { + private Button mDateButton; + private TextView mDateTextView; + private DatePicker mDatePicker; private DatePicker.OnDateChangedListener mDateListener; private boolean hideDay = false; @@ -121,6 +129,11 @@ public void onDateChanged(DatePicker view, int year, int month, int day) { // If there's an answer, use it. setAnswer(); + + + createDateButton(); + createDateTextView(); + addViews(); } /** @@ -229,14 +242,49 @@ public void setFocus(Context context) { @Override public void setOnLongClickListener(OnLongClickListener l) { - mDatePicker.setOnLongClickListener(l); + mDateButton.setOnLongClickListener(l); + mDateTextView.setOnLongClickListener(l); } @Override public void cancelLongPress() { super.cancelLongPress(); - mDatePicker.cancelLongPress(); + mDateButton.cancelLongPress(); + mDateTextView.cancelLongPress(); + } + + private void createDateButton() { + TableLayout.LayoutParams params = new TableLayout.LayoutParams(); + params.setMargins(7, 5, 7, 5); + + mDateButton = new Button(getContext()); + mDateButton.setId(QuestionWidget.newUniqueId()); + mDateButton.setText(R.string.select_time); + mDateButton.setPadding(20, 20, 20, 20); + mDateButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mAnswerFontsize); + mDateButton.setLayoutParams(params); + mDateButton.setEnabled(!mPrompt.isReadOnly()); + + mDateButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + } + }); } + private void createDateTextView() { + mDateTextView = new TextView(getContext()); + mDateTextView.setId(QuestionWidget.newUniqueId()); + mDateTextView.setPadding(20, 20, 20, 20); + mDateTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mAnswerFontsize); + } + + private void addViews() { + LinearLayout linearLayout = new LinearLayout(getContext()); + linearLayout.setOrientation(LinearLayout.VERTICAL); + linearLayout.addView(mDateButton); + linearLayout.addView(mDateTextView); + addAnswerView(linearLayout); + } } diff --git a/collect_app/src/main/res/values/strings.xml b/collect_app/src/main/res/values/strings.xml index 3989c426d9c..e95542b67b6 100644 --- a/collect_app/src/main/res/values/strings.xml +++ b/collect_app/src/main/res/values/strings.xml @@ -497,4 +497,5 @@ ODK Collect needs access to your Google account to get blank forms and submit filled forms. Filter the list Select time +Select date \ No newline at end of file From b865221b387cd7b30b8a33680de55e330c738d0b Mon Sep 17 00:00:00 2001 From: Grzegorz Orczykowski Date: Mon, 27 Mar 2017 12:29:33 +0200 Subject: [PATCH 06/25] DateWidget: Added DatePickerDialog --- .../collect/android/widgets/DateWidget.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java index a2e7d811a24..109f48cca65 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java @@ -15,6 +15,7 @@ package org.odk.collect.android.widgets; import android.annotation.SuppressLint; +import android.app.DatePickerDialog; import android.content.Context; import android.content.res.Resources; import android.os.Build; @@ -50,6 +51,7 @@ * @author Yaw Anokwa (yanokwa@gmail.com) */ public class DateWidget extends QuestionWidget { + private DatePickerDialog mDatePickerDialog; private Button mDateButton; private TextView mDateTextView; @@ -133,6 +135,7 @@ public void onDateChanged(DatePicker view, int year, int month, int day) { createDateButton(); createDateTextView(); + createDatePickerDialog(); addViews(); } @@ -287,4 +290,23 @@ private void addViews() { linearLayout.addView(mDateTextView); addAnswerView(linearLayout); } + + private void createDatePickerDialog() { + mDatePickerDialog = new DatePickerDialog(getContext(), + new DatePickerDialog.OnDateSetListener() { + @Override + public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { + } + }, 0, 0, 0); + + // If there's an answer, use it. + if (mPrompt.getAnswerValue() != null) { + // create a new date from date object using default time zone + DateTime ldt = new DateTime(((Date) mPrompt.getAnswerValue().getValue()).getTime()); + mDatePickerDialog.updateDate(ldt.getYear(), ldt.getMonthOfYear() - 1, ldt.getDayOfMonth()); + } else { + // create date widget with current time as of right now + clearAnswer(); + } + } } From d235a6604b51955ebb8dd25ab8666cb3bddd3035 Mon Sep 17 00:00:00 2001 From: Grzegorz Orczykowski Date: Mon, 27 Mar 2017 12:37:59 +0200 Subject: [PATCH 07/25] DateWidget: refactored hideDayFieldIfNotInFormat() method --- .../collect/android/widgets/DateWidget.java | 42 ++++--------------- 1 file changed, 8 insertions(+), 34 deletions(-) diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java index 109f48cca65..0af91e986ce 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java @@ -76,8 +76,6 @@ public DateWidget(Context context, FormEntryPrompt prompt) { DateWidgetUtils.fixCalendarViewIfJellyBean(mDatePicker.getCalendarView()); } - hideDayFieldIfNotInFormat(prompt); - mDateListener = new DatePicker.OnDateChangedListener() { @Override public void onDateChanged(DatePicker view, int year, int month, int day) { @@ -137,53 +135,29 @@ public void onDateChanged(DatePicker view, int year, int month, int day) { createDateTextView(); createDatePickerDialog(); addViews(); + hideDayFieldIfNotInFormat(); } - /** - * Shared between DateWidget and DateTimeWidget. - * There are extra appearance settings that do not apply for dateTime... - * TODO: move this into utilities or base class? - */ - @SuppressLint("NewApi") - private void hideDayFieldIfNotInFormat(FormEntryPrompt prompt) { - String appearance = prompt.getQuestion().getAppearanceAttr(); - if (appearance == null) { - showCalendar = true; - this.mDatePicker.setCalendarViewShown(true); - CalendarView cv = this.mDatePicker.getCalendarView(); - cv.setShowWeekNumber(false); - this.mDatePicker.setSpinnersShown(true); - hideDay = true; - hideMonth = false; - } else if ("month-year".equals(appearance)) { + private void hideDayFieldIfNotInFormat() { + String appearance = mPrompt.getQuestion().getAppearanceAttr(); + if ("month-year".equals(appearance)) { hideDay = true; - this.mDatePicker.setCalendarViewShown(false); - this.mDatePicker.setSpinnersShown(true); } else if ("year".equals(appearance)) { + hideDay = true; hideMonth = true; - this.mDatePicker.setCalendarViewShown(false); - this.mDatePicker.setSpinnersShown(true); } else if ("no-calendar".equals(appearance)) { - this.mDatePicker.setCalendarViewShown(false); - this.mDatePicker.setSpinnersShown(true); } else { showCalendar = true; - this.mDatePicker.setCalendarViewShown(true); - CalendarView cv = this.mDatePicker.getCalendarView(); - cv.setShowWeekNumber(false); - this.mDatePicker.setSpinnersShown(true); hideDay = true; - hideMonth = false; } if (hideMonth || hideDay) { - mDatePicker.findViewById( + mDatePickerDialog.getDatePicker().findViewById( Resources.getSystem().getIdentifier("day", "id", "android")) .setVisibility(View.GONE); if (hideMonth) { - mDatePicker - .findViewById( - Resources.getSystem().getIdentifier("month", "id", "android")) + mDatePickerDialog.getDatePicker().findViewById( + Resources.getSystem().getIdentifier("month", "id", "android")) .setVisibility(View.GONE); } } From 6002e2dad3b038c8950ef539f7616b832089ad6e Mon Sep 17 00:00:00 2001 From: Grzegorz Orczykowski Date: Mon, 27 Mar 2017 12:40:59 +0200 Subject: [PATCH 08/25] DateWidget: Removed unnecessary code --- .../collect/android/widgets/DateWidget.java | 104 ++---------------- 1 file changed, 8 insertions(+), 96 deletions(-) diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java index 0af91e986ce..77cbe4f12c9 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java @@ -56,86 +56,21 @@ public class DateWidget extends QuestionWidget { private Button mDateButton; private TextView mDateTextView; - private DatePicker mDatePicker; - private DatePicker.OnDateChangedListener mDateListener; private boolean hideDay = false; private boolean hideMonth = false; private boolean showCalendar = false; - private HorizontalScrollView scrollView = null; - public DateWidget(Context context, FormEntryPrompt prompt) { super(context, prompt); - mDatePicker = new DatePicker(getContext()); - mDatePicker.setId(QuestionWidget.newUniqueId()); - mDatePicker.setFocusable(!prompt.isReadOnly()); - mDatePicker.setEnabled(!prompt.isReadOnly()); - - if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN) { - DateWidgetUtils.fixCalendarViewIfJellyBean(mDatePicker.getCalendarView()); - } - - mDateListener = new DatePicker.OnDateChangedListener() { - @Override - public void onDateChanged(DatePicker view, int year, int month, int day) { - if (mPrompt.isReadOnly()) { - setAnswer(); - } else { - // TODO support dates <1900 >2100 - // handle leap years and number of days in month - // http://code.google.com/p/android/issues/detail?id=2081 - Calendar c = Calendar.getInstance(); - c.set(year, month, 1); - int max = c.getActualMaximum(Calendar.DAY_OF_MONTH); - // in older versions of android (1.6ish) the datepicker lets you pick bad dates - // in newer versions, calling updateDate() calls onDatechangedListener(), - // causing an - // endless loop. - if (day > max) { - if (!(mDatePicker.getDayOfMonth() == day && mDatePicker.getMonth() == month - && mDatePicker.getYear() == year)) { - Collect.getInstance().getActivityLogger().logInstanceAction( - DateWidget.this, "onDateChanged", - String.format("%1$04d-%2$02d-%3$02d", year, month, max), - mPrompt.getIndex()); - mDatePicker.updateDate(year, month, max); - } - } else { - if (!(mDatePicker.getDayOfMonth() == day && mDatePicker.getMonth() == month - && mDatePicker.getYear() == year)) { - Collect.getInstance().getActivityLogger().logInstanceAction( - DateWidget.this, "onDateChanged", - String.format("%1$04d-%2$02d-%3$02d", year, month, day), - mPrompt.getIndex()); - mDatePicker.updateDate(year, month, day); - } - } - } - } - }; - - setGravity(Gravity.LEFT); - if (showCalendar) { - scrollView = new HorizontalScrollView(context); - LinearLayout ll = new LinearLayout(context); - ll.addView(mDatePicker); - ll.setPadding(10, 10, 10, 10); - scrollView.addView(ll); - addAnswerView(scrollView); - } else { - addAnswerView(mDatePicker); - } - - // If there's an answer, use it. - setAnswer(); - - createDateButton(); createDateTextView(); createDatePickerDialog(); addViews(); hideDayFieldIfNotInFormat(); + if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN) { + DateWidgetUtils.fixCalendarViewIfJellyBean(mDatePickerDialog.getDatePicker().getCalendarView()); + } } private void hideDayFieldIfNotInFormat() { @@ -163,43 +98,23 @@ private void hideDayFieldIfNotInFormat() { } } - private void setAnswer() { - - if (mPrompt.getAnswerValue() != null) { - DateTime ldt = - new DateTime( - ((Date) mPrompt.getAnswerValue().getValue()).getTime()); - mDatePicker.init(ldt.getYear(), ldt.getMonthOfYear() - 1, ldt.getDayOfMonth(), - mDateListener); - } else { - // create date widget with current time as of right now - clearAnswer(); - } - } - - /** * Resets date to today. */ @Override public void clearAnswer() { - DateTime ldt = new DateTime(); - mDatePicker.init(ldt.getYear(), ldt.getMonthOfYear() - 1, ldt.getDayOfMonth(), - mDateListener); + DateTime dt = new DateTime(); + mDatePickerDialog.updateDate(dt.getYear(), dt.getMonthOfYear() - 1, dt.getDayOfMonth()); } - @Override public IAnswerData getAnswer() { - if (showCalendar) { - scrollView.clearChildFocus(mDatePicker); - } clearFocus(); LocalDateTime ldt = new LocalDateTime() - .withYear(mDatePicker.getYear()) - .withMonthOfYear((!showCalendar && hideMonth) ? 1 : mDatePicker.getMonth() + 1) - .withDayOfMonth((!showCalendar && (hideMonth || hideDay)) ? 1 : mDatePicker.getDayOfMonth()) + .withYear(mDatePickerDialog.getDatePicker().getYear()) + .withMonthOfYear((!showCalendar && hideMonth) ? 1 : mDatePickerDialog.getDatePicker().getMonth() + 1) + .withDayOfMonth((!showCalendar && (hideMonth || hideDay)) ? 1 : mDatePickerDialog.getDatePicker().getDayOfMonth()) .withHourOfDay(0) .withMinuteOfHour(0); @@ -207,7 +122,6 @@ public IAnswerData getAnswer() { return new DateData(ldt.toDate()); } - @Override public void setFocus(Context context) { // Hide the soft keyboard if it's showing. @@ -216,14 +130,12 @@ public void setFocus(Context context) { inputManager.hideSoftInputFromWindow(this.getWindowToken(), 0); } - @Override public void setOnLongClickListener(OnLongClickListener l) { mDateButton.setOnLongClickListener(l); mDateTextView.setOnLongClickListener(l); } - @Override public void cancelLongPress() { super.cancelLongPress(); From 4173b73a285a6919953d48ac9191d35b03a63b02 Mon Sep 17 00:00:00 2001 From: Grzegorz Orczykowski Date: Mon, 27 Mar 2017 12:42:31 +0200 Subject: [PATCH 09/25] DateWidget: Code refactoring --- .../collect/android/widgets/DateWidget.java | 30 ++++++++----------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java index 77cbe4f12c9..0ae0e30e78c 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java @@ -14,19 +14,15 @@ package org.odk.collect.android.widgets; -import android.annotation.SuppressLint; import android.app.DatePickerDialog; import android.content.Context; import android.content.res.Resources; import android.os.Build; import android.util.TypedValue; -import android.view.Gravity; import android.view.View; import android.view.inputmethod.InputMethodManager; import android.widget.Button; -import android.widget.CalendarView; import android.widget.DatePicker; -import android.widget.HorizontalScrollView; import android.widget.LinearLayout; import android.widget.TableLayout; import android.widget.TextView; @@ -37,10 +33,8 @@ import org.joda.time.DateTime; import org.joda.time.LocalDateTime; import org.odk.collect.android.R; -import org.odk.collect.android.application.Collect; import org.odk.collect.android.utilities.DateWidgetUtils; -import java.util.Calendar; import java.util.Date; /** @@ -56,9 +50,9 @@ public class DateWidget extends QuestionWidget { private Button mDateButton; private TextView mDateTextView; - private boolean hideDay = false; - private boolean hideMonth = false; - private boolean showCalendar = false; + private boolean mHideDay; + private boolean mHideMonth; + private boolean mShowCalendar; public DateWidget(Context context, FormEntryPrompt prompt) { super(context, prompt); @@ -76,21 +70,21 @@ public DateWidget(Context context, FormEntryPrompt prompt) { private void hideDayFieldIfNotInFormat() { String appearance = mPrompt.getQuestion().getAppearanceAttr(); if ("month-year".equals(appearance)) { - hideDay = true; + mHideDay = true; } else if ("year".equals(appearance)) { - hideDay = true; - hideMonth = true; + mHideDay = true; + mHideMonth = true; } else if ("no-calendar".equals(appearance)) { } else { - showCalendar = true; - hideDay = true; + mShowCalendar = true; + mHideDay = true; } - if (hideMonth || hideDay) { + if (mHideMonth || mHideDay) { mDatePickerDialog.getDatePicker().findViewById( Resources.getSystem().getIdentifier("day", "id", "android")) .setVisibility(View.GONE); - if (hideMonth) { + if (mHideMonth) { mDatePickerDialog.getDatePicker().findViewById( Resources.getSystem().getIdentifier("month", "id", "android")) .setVisibility(View.GONE); @@ -113,8 +107,8 @@ public IAnswerData getAnswer() { LocalDateTime ldt = new LocalDateTime() .withYear(mDatePickerDialog.getDatePicker().getYear()) - .withMonthOfYear((!showCalendar && hideMonth) ? 1 : mDatePickerDialog.getDatePicker().getMonth() + 1) - .withDayOfMonth((!showCalendar && (hideMonth || hideDay)) ? 1 : mDatePickerDialog.getDatePicker().getDayOfMonth()) + .withMonthOfYear((!mShowCalendar && mHideMonth) ? 1 : mDatePickerDialog.getDatePicker().getMonth() + 1) + .withDayOfMonth((!mShowCalendar && (mHideMonth || mHideDay)) ? 1 : mDatePickerDialog.getDatePicker().getDayOfMonth()) .withHourOfDay(0) .withMinuteOfHour(0); From 5cdbce07ddb2f9d98e3576cd589a6f8493a27e7b Mon Sep 17 00:00:00 2001 From: Grzegorz Orczykowski Date: Mon, 27 Mar 2017 12:46:26 +0200 Subject: [PATCH 10/25] DateWidget: Implemented setDate() method --- .../odk/collect/android/widgets/DateWidget.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java index 0ae0e30e78c..000d21d904e 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java @@ -99,6 +99,7 @@ private void hideDayFieldIfNotInFormat() { public void clearAnswer() { DateTime dt = new DateTime(); mDatePickerDialog.updateDate(dt.getYear(), dt.getMonthOfYear() - 1, dt.getDayOfMonth()); + setDate(); } @Override @@ -171,6 +172,18 @@ private void addViews() { addAnswerView(linearLayout); } + private void setDate() { + int dayOfMonth = mDatePickerDialog.getDatePicker().getDayOfMonth(); + int monthOfYear = mDatePickerDialog.getDatePicker().getMonth() + 1; + int year = mDatePickerDialog.getDatePicker().getYear(); + + String dayText = dayOfMonth < 10 ? "0" + dayOfMonth : "" + dayOfMonth; + String monthText = monthOfYear < 10 ? "0" + monthOfYear : "" + monthOfYear; + String yearText = year < 10 ? "0" + year : "" + year; + + mDateTextView.setText(dayText + "/" + monthText + "/" + yearText); + } + private void createDatePickerDialog() { mDatePickerDialog = new DatePickerDialog(getContext(), new DatePickerDialog.OnDateSetListener() { @@ -184,6 +197,7 @@ public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth // create a new date from date object using default time zone DateTime ldt = new DateTime(((Date) mPrompt.getAnswerValue().getValue()).getTime()); mDatePickerDialog.updateDate(ldt.getYear(), ldt.getMonthOfYear() - 1, ldt.getDayOfMonth()); + setDate(); } else { // create date widget with current time as of right now clearAnswer(); From 665e85a0fb1369533f45c5692aa67aaf7733ad85 Mon Sep 17 00:00:00 2001 From: Grzegorz Orczykowski Date: Mon, 27 Mar 2017 13:16:49 +0200 Subject: [PATCH 11/25] DateWidget: Fixed some bugs --- .../collect/android/widgets/DateWidget.java | 52 ++++++++++++------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java index 000d21d904e..3a7f75dfa82 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java @@ -69,25 +69,30 @@ public DateWidget(Context context, FormEntryPrompt prompt) { private void hideDayFieldIfNotInFormat() { String appearance = mPrompt.getQuestion().getAppearanceAttr(); - if ("month-year".equals(appearance)) { - mHideDay = true; - } else if ("year".equals(appearance)) { - mHideDay = true; - mHideMonth = true; - } else if ("no-calendar".equals(appearance)) { - } else { - mShowCalendar = true; - mHideDay = true; - } + if (!"no-calendar".equals(appearance)) { + if ("month-year".equals(appearance)) { + mHideDay = true; + } else if ("year".equals(appearance)) { + mHideDay = true; + mHideMonth = true; + } else { + mShowCalendar = true; + mHideDay = true; + } + + if (mShowCalendar) { + mDatePickerDialog.getDatePicker().setCalendarViewShown(true); + } - if (mHideMonth || mHideDay) { - mDatePickerDialog.getDatePicker().findViewById( - Resources.getSystem().getIdentifier("day", "id", "android")) - .setVisibility(View.GONE); - if (mHideMonth) { + if (mHideMonth || mHideDay) { mDatePickerDialog.getDatePicker().findViewById( - Resources.getSystem().getIdentifier("month", "id", "android")) + Resources.getSystem().getIdentifier("day", "id", "android")) .setVisibility(View.GONE); + if (mHideMonth) { + mDatePickerDialog.getDatePicker().findViewById( + Resources.getSystem().getIdentifier("month", "id", "android")) + .setVisibility(View.GONE); + } } } } @@ -144,7 +149,7 @@ private void createDateButton() { mDateButton = new Button(getContext()); mDateButton.setId(QuestionWidget.newUniqueId()); - mDateButton.setText(R.string.select_time); + mDateButton.setText(R.string.select_date); mDateButton.setPadding(20, 20, 20, 20); mDateButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mAnswerFontsize); mDateButton.setLayoutParams(params); @@ -153,6 +158,7 @@ private void createDateButton() { mDateButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { + mDatePickerDialog.show(); } }); } @@ -179,9 +185,15 @@ private void setDate() { String dayText = dayOfMonth < 10 ? "0" + dayOfMonth : "" + dayOfMonth; String monthText = monthOfYear < 10 ? "0" + monthOfYear : "" + monthOfYear; - String yearText = year < 10 ? "0" + year : "" + year; - mDateTextView.setText(dayText + "/" + monthText + "/" + yearText); + String appearance = mPrompt.getQuestion().getAppearanceAttr(); + if ("month-year".equals(appearance)) { + mDateTextView.setText(monthText + "/" + year); + } else if ("year".equals(appearance)) { + mDateTextView.setText(String.valueOf(year)); + } else { + mDateTextView.setText(dayText + "/" + monthText + "/" + year); + } } private void createDatePickerDialog() { @@ -189,6 +201,8 @@ private void createDatePickerDialog() { new DatePickerDialog.OnDateSetListener() { @Override public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { + mDatePickerDialog.updateDate(year, monthOfYear, dayOfMonth); + setDate(); } }, 0, 0, 0); From dc7d3b7bdef6700fbe56b1a4a70cd4cab98f3648 Mon Sep 17 00:00:00 2001 From: Grzegorz Orczykowski Date: Mon, 27 Mar 2017 14:38:29 +0200 Subject: [PATCH 12/25] Added new DateTimeWidget --- .../collect/android/views/MediaLayout.java | 4 + .../android/widgets/DateTimeWidget.java | 247 +++--------------- .../collect/android/widgets/DateWidget.java | 24 ++ .../android/widgets/QuestionWidget.java | 2 +- .../collect/android/widgets/TimeWidget.java | 8 + 5 files changed, 72 insertions(+), 213 deletions(-) diff --git a/collect_app/src/main/java/org/odk/collect/android/views/MediaLayout.java b/collect_app/src/main/java/org/odk/collect/android/views/MediaLayout.java index 8a8951e8e64..811d8a7bc50 100644 --- a/collect_app/src/main/java/org/odk/collect/android/views/MediaLayout.java +++ b/collect_app/src/main/java/org/odk/collect/android/views/MediaLayout.java @@ -425,6 +425,10 @@ public void setTextcolor(int color) { mView_Text.setTextColor(color); } + public TextView getView_Text() { + return mView_Text; + } + /** * This is what gets called when the AudioButton gets clicked */ diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/DateTimeWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/DateTimeWidget.java index d6bba5cc8b5..6b4eb542c23 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/DateTimeWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/DateTimeWidget.java @@ -14,30 +14,14 @@ package org.odk.collect.android.widgets; -import android.annotation.SuppressLint; import android.content.Context; -import android.content.res.Resources; -import android.os.Build; -import android.view.Gravity; -import android.view.View; import android.view.inputmethod.InputMethodManager; -import android.widget.CalendarView; -import android.widget.DatePicker; -import android.widget.HorizontalScrollView; import android.widget.LinearLayout; -import android.widget.TimePicker; import org.javarosa.core.model.data.DateTimeData; import org.javarosa.core.model.data.IAnswerData; import org.javarosa.form.api.FormEntryPrompt; -import org.joda.time.DateTime; import org.joda.time.LocalDateTime; -import org.odk.collect.android.application.Collect; -import org.odk.collect.android.utilities.DateWidgetUtils; - -import java.util.Calendar; -import java.util.Date; - /** * Displays a DatePicker widget. DateWidget handles leap years and does not allow dates that do not * exist. @@ -47,214 +31,56 @@ */ public class DateTimeWidget extends QuestionWidget { - private DatePicker mDatePicker; - private TimePicker mTimePicker; - private DatePicker.OnDateChangedListener mDateListener; - private boolean hideDay = false; - private boolean hideMonth = false; - private boolean showCalendar = false; - private HorizontalScrollView scrollView = null; + private DateWidget mDateWidget; + private TimeWidget mTimeWidget; public DateTimeWidget(Context context, FormEntryPrompt prompt) { super(context, prompt); - mDatePicker = new DatePicker(getContext()); - mDatePicker.setId(QuestionWidget.newUniqueId()); - mDatePicker.setFocusable(!prompt.isReadOnly()); - mDatePicker.setEnabled(!prompt.isReadOnly()); - - if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN) { - DateWidgetUtils.fixCalendarViewIfJellyBean(mDatePicker.getCalendarView()); - } - - mTimePicker = new TimePicker(getContext()); - mTimePicker.setId(QuestionWidget.newUniqueId()); - mTimePicker.setFocusable(!prompt.isReadOnly()); - mTimePicker.setEnabled(!prompt.isReadOnly()); - mTimePicker.setPadding(0, 20, 0, 0); - - String clockType = - android.provider.Settings.System.getString(context.getContentResolver(), - android.provider.Settings.System.TIME_12_24); - if (clockType == null || clockType.equalsIgnoreCase("24")) { - mTimePicker.setIs24HourView(true); - } - - hideDayFieldIfNotInFormat(prompt); - - mDateListener = new DatePicker.OnDateChangedListener() { - @Override - public void onDateChanged(DatePicker view, int year, int month, int day) { - if (mPrompt.isReadOnly()) { - setAnswer(); - } else { - // handle leap years and number of days in month - // TODO - // http://code.google.com/p/android/issues/detail?id=2081 - // in older versions of android (1.6ish) the datepicker lets you pick bad dates - // in newer versions, calling updateDate() calls onDatechangedListener(), - // causing an - // endless loop. - Calendar c = Calendar.getInstance(); - c.set(year, month, 1); - int max = c.getActualMaximum(Calendar.DAY_OF_MONTH); - if (day > max) { - if (!(mDatePicker.getDayOfMonth() == day && mDatePicker.getMonth() == month - && mDatePicker.getYear() == year)) { - Collect.getInstance().getActivityLogger().logInstanceAction( - DateTimeWidget.this, "onDateChanged", - String.format("%1$04d-%2$02d-%3$02d", year, month, max), - mPrompt.getIndex()); - mDatePicker.updateDate(year, month, max); - } - } else { - if (!(mDatePicker.getDayOfMonth() == day && mDatePicker.getMonth() == month - && mDatePicker.getYear() == year)) { - Collect.getInstance().getActivityLogger().logInstanceAction( - DateTimeWidget.this, "onDateChanged", - String.format("%1$04d-%2$02d-%3$02d", year, month, day), - mPrompt.getIndex()); - mDatePicker.updateDate(year, month, day); - } - } - } - } - }; - - mTimePicker.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() { - @Override - public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { - Collect.getInstance().getActivityLogger().logInstanceAction(DateTimeWidget.this, - "onTimeChanged", - String.format("%1$02d:%2$02d", hourOfDay, minute), mPrompt.getIndex()); - } - }); + mDateWidget = new DateWidget(context, prompt); + mTimeWidget= new TimeWidget(context, prompt); - setGravity(Gravity.START); - LinearLayout answerLayout = new LinearLayout(getContext()); - answerLayout.setOrientation(LinearLayout.VERTICAL); - if (showCalendar) { - scrollView = new HorizontalScrollView(context); - LinearLayout ll = new LinearLayout(context); - ll.addView(mDatePicker); - ll.setPadding(10, 10, 10, 10); - scrollView.addView(ll); - answerLayout.addView(scrollView); - } else { - answerLayout.addView(mDatePicker); - } - answerLayout.addView(mTimePicker); - addAnswerView(answerLayout); + mDateWidget.mQuestionMediaLayout.getView_Text().setVisibility(GONE); + mTimeWidget.mQuestionMediaLayout.getView_Text().setVisibility(GONE); - // If there's an answer, use it. - setAnswer(); + LinearLayout linearLayout = new LinearLayout(getContext()); + linearLayout.setOrientation(LinearLayout.VERTICAL); + linearLayout.addView(mDateWidget); + linearLayout.addView(mTimeWidget); + addAnswerView(linearLayout); } - - /** - * Shared between DateWidget and DateTimeWidget. - * There are extra appearance settings that do not apply for dateTime... - * TODO: move this into utilities or base class? - */ - @SuppressLint("NewApi") - private void hideDayFieldIfNotInFormat(FormEntryPrompt prompt) { - String appearance = prompt.getQuestion().getAppearanceAttr(); - if (appearance == null) { - showCalendar = true; - this.mDatePicker.setCalendarViewShown(true); - CalendarView cv = this.mDatePicker.getCalendarView(); - cv.setShowWeekNumber(false); - this.mDatePicker.setSpinnersShown(true); - hideDay = true; - hideMonth = false; - } else if ("month-year".equals(appearance)) { - hideDay = true; - this.mDatePicker.setCalendarViewShown(false); - this.mDatePicker.setSpinnersShown(true); - mTimePicker.setVisibility(GONE); - } else if ("year".equals(appearance)) { - hideMonth = true; - this.mDatePicker.setCalendarViewShown(false); - this.mDatePicker.setSpinnersShown(true); - mTimePicker.setVisibility(GONE); - } else if ("no-calendar".equals(appearance)) { - this.mDatePicker.setCalendarViewShown(false); - this.mDatePicker.setSpinnersShown(true); - } else { - showCalendar = true; - this.mDatePicker.setCalendarViewShown(true); - CalendarView cv = this.mDatePicker.getCalendarView(); - cv.setShowWeekNumber(false); - this.mDatePicker.setSpinnersShown(true); - hideDay = true; - hideMonth = false; - } - - if (hideMonth || hideDay) { - mDatePicker.findViewById( - Resources.getSystem().getIdentifier("day", "id", "android")) - .setVisibility(View.GONE); - if (hideMonth) { - mDatePicker - .findViewById( - Resources.getSystem().getIdentifier("month", "id", "android")) - .setVisibility(View.GONE); - } - } - } - - private void setAnswer() { - - if (mPrompt.getAnswerValue() != null) { - - DateTime ldt = - new DateTime( - ((Date) mPrompt.getAnswerValue().getValue()).getTime - ()); - mDatePicker.init(ldt.getYear(), ldt.getMonthOfYear() - 1, ldt.getDayOfMonth(), - mDateListener); - mTimePicker.setCurrentHour(ldt.getHourOfDay()); - mTimePicker.setCurrentMinute(ldt.getMinuteOfHour()); - - } else { - // create time widget with current time as of right now - clearAnswer(); - } - } - - - /** - * Resets date to today. - */ - @Override - public void clearAnswer() { - DateTime ldt = new DateTime(); - mDatePicker.init(ldt.getYear(), ldt.getMonthOfYear() - 1, ldt.getDayOfMonth(), - mDateListener); - mTimePicker.setCurrentHour(ldt.getHourOfDay()); - mTimePicker.setCurrentMinute(ldt.getMinuteOfHour()); - } - - @Override public IAnswerData getAnswer() { - if (showCalendar) { - scrollView.clearChildFocus(mDatePicker); - } clearFocus(); + boolean showCalendar = mDateWidget.isCalendarShown(); + boolean hideDay = mDateWidget.isDayHidden(); + boolean hideMonth = mDateWidget.isMonthHidden(); + + int year = mDateWidget.getYear(); + int month = mDateWidget.getMonth(); + int day = mDateWidget.getDay(); + int hour = mTimeWidget.getHour(); + int minute = mTimeWidget.getMinute(); + LocalDateTime ldt = new LocalDateTime() - .withYear(mDatePicker.getYear()) - .withMonthOfYear((!showCalendar && hideMonth) ? 1 : mDatePicker.getMonth() + 1) - .withDayOfMonth((!showCalendar && (hideMonth || hideDay)) ? 1 : mDatePicker.getDayOfMonth()) - .withHourOfDay((!showCalendar && (hideMonth || hideDay)) ? 0 : mTimePicker.getCurrentHour()) - .withMinuteOfHour((!showCalendar && (hideMonth || hideDay)) ? 0 : mTimePicker.getCurrentMinute()) + .withYear(year) + .withMonthOfYear((!showCalendar && hideMonth) ? 1 : month) + .withDayOfMonth((!showCalendar && (hideMonth || hideDay)) ? 1 : day) + .withHourOfDay((!showCalendar && (hideMonth || hideDay)) ? 0 : hour) + .withMinuteOfHour((!showCalendar && (hideMonth || hideDay)) ? 0 : minute) .withSecondOfMinute(0); ldt = skipDaylightSavingGapIfExists(ldt); return new DateTimeData(ldt.toDate()); } + @Override + public void clearAnswer() { + mDateWidget.clearAnswer(); + mTimeWidget.clearAnswer(); + } @Override public void setFocus(Context context) { @@ -264,19 +90,16 @@ public void setFocus(Context context) { inputManager.hideSoftInputFromWindow(this.getWindowToken(), 0); } - @Override public void setOnLongClickListener(OnLongClickListener l) { - mDatePicker.setOnLongClickListener(l); - mTimePicker.setOnLongClickListener(l); + mDateWidget.setOnLongClickListener(l); + mTimeWidget.setOnLongClickListener(l); } - @Override public void cancelLongPress() { super.cancelLongPress(); - mDatePicker.cancelLongPress(); - mTimePicker.cancelLongPress(); + mDateWidget.cancelLongPress(); + mTimeWidget.cancelLongPress(); } - } diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java index 3a7f75dfa82..3d44bd30bbf 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java @@ -217,4 +217,28 @@ public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth clearAnswer(); } } + + public boolean isCalendarShown() { + return mShowCalendar; + } + + public boolean isDayHidden() { + return mHideDay; + } + + public boolean isMonthHidden() { + return mHideMonth; + } + + public int getYear() { + return mDatePickerDialog.getDatePicker().getYear(); + } + + public int getMonth() { + return mDatePickerDialog.getDatePicker().getMonth() + 1; + } + + public int getDay() { + return mDatePickerDialog.getDatePicker().getDayOfMonth(); + } } diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/QuestionWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/QuestionWidget.java index eb792656a29..8ac6cb37c9d 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/QuestionWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/QuestionWidget.java @@ -63,11 +63,11 @@ public static int newUniqueId() { } protected FormEntryPrompt mPrompt; + protected MediaLayout mQuestionMediaLayout; protected final int mQuestionFontsize; protected final int mAnswerFontsize; - private MediaLayout mQuestionMediaLayout; private TextView mHelpTextView; protected MediaPlayer mPlayer; diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java index d42c66a5c31..f55dc7b818a 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java @@ -165,4 +165,12 @@ public void onTimeSet(TimePicker view, int hourOfDay, int minuteOfHour) { clearAnswer(); } } + + public int getHour() { + return mHourOfDay; + } + + public int getMinute() { + return mMinuteOfHour; + } } From 63c051efe054ae268d0e7d21991a68dc98ae098c Mon Sep 17 00:00:00 2001 From: Grzegorz Orczykowski Date: Wed, 29 Mar 2017 11:10:56 +0200 Subject: [PATCH 13/25] Fixed bugs and lints --- .../org/odk/collect/android/widgets/DateTimeWidget.java | 3 +++ .../java/org/odk/collect/android/widgets/DateWidget.java | 7 +++++-- .../java/org/odk/collect/android/widgets/TimeWidget.java | 2 +- collect_app/src/main/res/values/untranslated.xml | 5 ++++- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/DateTimeWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/DateTimeWidget.java index 6b4eb542c23..e52c8319da7 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/DateTimeWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/DateTimeWidget.java @@ -15,6 +15,7 @@ package org.odk.collect.android.widgets; import android.content.Context; +import android.view.Gravity; import android.view.inputmethod.InputMethodManager; import android.widget.LinearLayout; @@ -37,6 +38,8 @@ public class DateTimeWidget extends QuestionWidget { public DateTimeWidget(Context context, FormEntryPrompt prompt) { super(context, prompt); + setGravity(Gravity.START); + mDateWidget = new DateWidget(context, prompt); mTimeWidget= new TimeWidget(context, prompt); diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java index 3d44bd30bbf..8c7db0dd1b1 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java @@ -19,6 +19,7 @@ import android.content.res.Resources; import android.os.Build; import android.util.TypedValue; +import android.view.Gravity; import android.view.View; import android.view.inputmethod.InputMethodManager; import android.widget.Button; @@ -57,6 +58,8 @@ public class DateWidget extends QuestionWidget { public DateWidget(Context context, FormEntryPrompt prompt) { super(context, prompt); + setGravity(Gravity.START); + createDateButton(); createDateTextView(); createDatePickerDialog(); @@ -188,11 +191,11 @@ private void setDate() { String appearance = mPrompt.getQuestion().getAppearanceAttr(); if ("month-year".equals(appearance)) { - mDateTextView.setText(monthText + "/" + year); + mDateTextView.setText(getContext().getString(R.string.date_year_month, monthText, String.valueOf(year))); } else if ("year".equals(appearance)) { mDateTextView.setText(String.valueOf(year)); } else { - mDateTextView.setText(dayText + "/" + monthText + "/" + year); + mDateTextView.setText(getContext().getString(R.string.full_date, dayText, monthText, String.valueOf(year))); } } diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java index 55af72f0a73..7391be66a4e 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java @@ -142,7 +142,7 @@ private void setTime(int hourOfDay, int minuteOfHour) { String hour = mHourOfDay < 10 ? "0" + mHourOfDay : "" + mHourOfDay; String minute = mMinuteOfHour < 10 ? "0" + mMinuteOfHour : "" + mMinuteOfHour; - mTimeTextView.setText(hour + ":" + minute); + mTimeTextView.setText(getContext().getString(R.string.time, hour, minute)); } private void createTimePickerDialog() { diff --git a/collect_app/src/main/res/values/untranslated.xml b/collect_app/src/main/res/values/untranslated.xml index fc232cb8ac5..e7997157301 100644 --- a/collect_app/src/main/res/values/untranslated.xml +++ b/collect_app/src/main/res/values/untranslated.xml @@ -16,5 +16,8 @@ https://opendatakit.appspot.com /formList /submission - + %1$s:%2$s + %1$s/%2$s/%3$s + %1$s/%2$s + From 09509340cd0f1bb77337f5ea4ac8cf51800a774e Mon Sep 17 00:00:00 2001 From: Grzegorz Orczykowski Date: Fri, 31 Mar 2017 11:57:17 +0200 Subject: [PATCH 14/25] Removed calendar appearance --- .../android/utilities/DateWidgetUtils.java | 74 ------------------- .../android/widgets/DateTimeWidget.java | 9 +-- .../collect/android/widgets/DateWidget.java | 53 +++++-------- 3 files changed, 21 insertions(+), 115 deletions(-) delete mode 100644 collect_app/src/main/java/org/odk/collect/android/utilities/DateWidgetUtils.java diff --git a/collect_app/src/main/java/org/odk/collect/android/utilities/DateWidgetUtils.java b/collect_app/src/main/java/org/odk/collect/android/utilities/DateWidgetUtils.java deleted file mode 100644 index 86de67f62ac..00000000000 --- a/collect_app/src/main/java/org/odk/collect/android/utilities/DateWidgetUtils.java +++ /dev/null @@ -1,74 +0,0 @@ -package org.odk.collect.android.utilities; - -import android.util.Log; -import android.view.View; -import android.view.ViewGroup; -import android.widget.CalendarView; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; - -/** - * The function fixCalendarViewIfJellyBean fixes the Calendar view bug for Android 4.1.2 devices - * - * For more info read the complete solution at this link : http://stackoverflow.com/a/36321828/5479029 - */ - -public class DateWidgetUtils { - - public static void fixCalendarViewIfJellyBean(CalendarView calendarView) { - try { - Object object = calendarView; - Field[] fields = object.getClass().getDeclaredFields(); - for (Field field : fields) { - if (field.getName().equals("mDelegate")) { // the CalendarViewLegacyDelegate instance is stored in this variable - field.setAccessible(true); - object = field.get(object); - break; - } - } - - Field field = object.getClass().getDeclaredField("mDateTextSize"); // text size integer value - field.setAccessible(true); - final int mDateTextSize = (Integer) field.get(object); - - field = object.getClass().getDeclaredField("mListView"); // main ListView - field.setAccessible(true); - Object innerObject = field.get(object); - - Method method = innerObject.getClass().getMethod( - "setOnHierarchyChangeListener", ViewGroup.OnHierarchyChangeListener.class); // we need to set the OnHierarchyChangeListener - method.setAccessible(true); - method.invoke(innerObject, (Object) new ViewGroup.OnHierarchyChangeListener() { - @Override - public void onChildViewAdded(View parent, View child) { // apply text size every time when a new child view is added - try { - Object object = child; - Field[] fields = object.getClass().getDeclaredFields(); - for (Field field : fields) { - if (field.getName().equals("mMonthNumDrawPaint")) { // the paint is stored inside the view - field.setAccessible(true); - object = field.get(object); - Method method = object.getClass(). - getDeclaredMethod("setTextSize", float.class); // finally set text size - method.setAccessible(true); - method.invoke(object, (Object) mDateTextSize); - - break; - } - } - } catch (Exception e) { - Log.e("DateTimeWidget", e.getMessage(), e); - } - } - - @Override - public void onChildViewRemoved(View parent, View child) { - } - }); - } catch (Exception e) { - Log.e("DateTimeWidget", e.getMessage(), e); - } - } - -} diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/DateTimeWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/DateTimeWidget.java index e52c8319da7..9669399afa6 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/DateTimeWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/DateTimeWidget.java @@ -57,7 +57,6 @@ public DateTimeWidget(Context context, FormEntryPrompt prompt) { public IAnswerData getAnswer() { clearFocus(); - boolean showCalendar = mDateWidget.isCalendarShown(); boolean hideDay = mDateWidget.isDayHidden(); boolean hideMonth = mDateWidget.isMonthHidden(); @@ -69,10 +68,10 @@ public IAnswerData getAnswer() { LocalDateTime ldt = new LocalDateTime() .withYear(year) - .withMonthOfYear((!showCalendar && hideMonth) ? 1 : month) - .withDayOfMonth((!showCalendar && (hideMonth || hideDay)) ? 1 : day) - .withHourOfDay((!showCalendar && (hideMonth || hideDay)) ? 0 : hour) - .withMinuteOfHour((!showCalendar && (hideMonth || hideDay)) ? 0 : minute) + .withMonthOfYear(hideMonth ? 1 : month) + .withDayOfMonth(hideMonth || hideDay ? 1 : day) + .withHourOfDay(hideMonth || hideDay ? 0 : hour) + .withMinuteOfHour(hideMonth || hideDay ? 0 : minute) .withSecondOfMinute(0); ldt = skipDaylightSavingGapIfExists(ldt); diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java index 8c7db0dd1b1..c2b65d11f17 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java @@ -17,7 +17,6 @@ import android.app.DatePickerDialog; import android.content.Context; import android.content.res.Resources; -import android.os.Build; import android.util.TypedValue; import android.view.Gravity; import android.view.View; @@ -34,7 +33,6 @@ import org.joda.time.DateTime; import org.joda.time.LocalDateTime; import org.odk.collect.android.R; -import org.odk.collect.android.utilities.DateWidgetUtils; import java.util.Date; @@ -53,7 +51,6 @@ public class DateWidget extends QuestionWidget { private boolean mHideDay; private boolean mHideMonth; - private boolean mShowCalendar; public DateWidget(Context context, FormEntryPrompt prompt) { super(context, prompt); @@ -65,38 +62,26 @@ public DateWidget(Context context, FormEntryPrompt prompt) { createDatePickerDialog(); addViews(); hideDayFieldIfNotInFormat(); - if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN) { - DateWidgetUtils.fixCalendarViewIfJellyBean(mDatePickerDialog.getDatePicker().getCalendarView()); - } } private void hideDayFieldIfNotInFormat() { String appearance = mPrompt.getQuestion().getAppearanceAttr(); - if (!"no-calendar".equals(appearance)) { - if ("month-year".equals(appearance)) { - mHideDay = true; - } else if ("year".equals(appearance)) { - mHideDay = true; - mHideMonth = true; - } else { - mShowCalendar = true; - mHideDay = true; - } - - if (mShowCalendar) { - mDatePickerDialog.getDatePicker().setCalendarViewShown(true); - } + if ("month-year".equals(appearance)) { + mHideDay = true; + } else if ("year".equals(appearance)) { + mHideDay = true; + mHideMonth = true; + } - if (mHideMonth || mHideDay) { - mDatePickerDialog.getDatePicker().findViewById( - Resources.getSystem().getIdentifier("day", "id", "android")) - .setVisibility(View.GONE); - if (mHideMonth) { - mDatePickerDialog.getDatePicker().findViewById( - Resources.getSystem().getIdentifier("month", "id", "android")) - .setVisibility(View.GONE); - } - } + if (mHideDay) { + mDatePickerDialog.getDatePicker().findViewById( + Resources.getSystem().getIdentifier("day", "id", "android")) + .setVisibility(View.GONE); + } + if (mHideMonth) { + mDatePickerDialog.getDatePicker().findViewById( + Resources.getSystem().getIdentifier("month", "id", "android")) + .setVisibility(View.GONE); } } @@ -116,8 +101,8 @@ public IAnswerData getAnswer() { LocalDateTime ldt = new LocalDateTime() .withYear(mDatePickerDialog.getDatePicker().getYear()) - .withMonthOfYear((!mShowCalendar && mHideMonth) ? 1 : mDatePickerDialog.getDatePicker().getMonth() + 1) - .withDayOfMonth((!mShowCalendar && (mHideMonth || mHideDay)) ? 1 : mDatePickerDialog.getDatePicker().getDayOfMonth()) + .withMonthOfYear(mHideMonth ? 1 : mDatePickerDialog.getDatePicker().getMonth() + 1) + .withDayOfMonth(mHideMonth || mHideDay ? 1 : mDatePickerDialog.getDatePicker().getDayOfMonth()) .withHourOfDay(0) .withMinuteOfHour(0); @@ -221,10 +206,6 @@ public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth } } - public boolean isCalendarShown() { - return mShowCalendar; - } - public boolean isDayHidden() { return mHideDay; } From 96ef6b06ef02491921ba705b01d41835bd8269b6 Mon Sep 17 00:00:00 2001 From: Grzegorz Orczykowski Date: Fri, 31 Mar 2017 12:08:00 +0200 Subject: [PATCH 15/25] Hide dialog title --- .../main/java/org/odk/collect/android/widgets/DateWidget.java | 1 + .../main/java/org/odk/collect/android/widgets/TimeWidget.java | 1 + 2 files changed, 2 insertions(+) diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java index c2b65d11f17..26177151f61 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java @@ -193,6 +193,7 @@ public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth setDate(); } }, 0, 0, 0); + mDatePickerDialog.setCustomTitle(new LinearLayout(getContext())); // If there's an answer, use it. if (mPrompt.getAnswerValue() != null) { diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java index 7391be66a4e..4f7ad21c61a 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java @@ -153,6 +153,7 @@ public void onTimeSet(TimePicker view, int hourOfDay, int minuteOfHour) { setTime(hourOfDay, minuteOfHour); } }, 0, 0, DateFormat.is24HourFormat(getContext())); + mTimePickerDialog.setCustomTitle(new LinearLayout(getContext())); // If there's an answer, use it. if (mPrompt.getAnswerValue() != null) { From 8b9ad9ddd8bee0f78f6de965daf52469d1a6de56 Mon Sep 17 00:00:00 2001 From: Grzegorz Orczykowski Date: Fri, 7 Apr 2017 18:36:04 +0200 Subject: [PATCH 16/25] Update strings.xml --- collect_app/src/main/res/values/strings.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/collect_app/src/main/res/values/strings.xml b/collect_app/src/main/res/values/strings.xml index 2effbc4909f..36ce8728865 100644 --- a/collect_app/src/main/res/values/strings.xml +++ b/collect_app/src/main/res/values/strings.xml @@ -499,4 +499,5 @@ Device ID Subscriber ID SIM serial number - \ No newline at end of file +Select time + From 2b37745d29172c7a4ecc9795dc645cf430d30e5a Mon Sep 17 00:00:00 2001 From: Grzegorz Orczykowski Date: Sun, 9 Apr 2017 22:16:16 +0200 Subject: [PATCH 17/25] Update strings.xml --- collect_app/src/main/res/values/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/collect_app/src/main/res/values/strings.xml b/collect_app/src/main/res/values/strings.xml index 95ed60711b9..7f83943fcb1 100644 --- a/collect_app/src/main/res/values/strings.xml +++ b/collect_app/src/main/res/values/strings.xml @@ -499,5 +499,6 @@ Device ID Subscriber ID SIM serial number +Select date Select time From 314646a589560e4ba10d482ffccabdfb2ae00108 Mon Sep 17 00:00:00 2001 From: grzegorz Date: Mon, 10 Apr 2017 11:33:25 +0300 Subject: [PATCH 18/25] Fixed test --- .../android/utilities/DaylightSavingTest.java | 37 +++++++++++-------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/collect_app/src/test/java/org/odk/collect/android/utilities/DaylightSavingTest.java b/collect_app/src/test/java/org/odk/collect/android/utilities/DaylightSavingTest.java index 2a7fede372e..86d746eab56 100644 --- a/collect_app/src/test/java/org/odk/collect/android/utilities/DaylightSavingTest.java +++ b/collect_app/src/test/java/org/odk/collect/android/utilities/DaylightSavingTest.java @@ -15,11 +15,13 @@ */ package org.odk.collect.android.utilities; +import android.app.DatePickerDialog; import android.widget.DatePicker; import android.widget.TimePicker; import org.javarosa.core.model.IFormElement; import org.javarosa.core.model.QuestionDef; +import org.javarosa.core.model.data.IAnswerData; import org.javarosa.form.api.FormEntryPrompt; import org.junit.After; import org.junit.Before; @@ -29,6 +31,7 @@ import org.odk.collect.android.BuildConfig; import org.odk.collect.android.widgets.DateTimeWidget; import org.odk.collect.android.widgets.DateWidget; +import org.odk.collect.android.widgets.TimeWidget; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; @@ -68,7 +71,7 @@ public void tearDown() { // 26 Mar 2017 at 02:00:00 clocks were turned forward to 03:00:00. public void testESTTimeZoneWithDateTimeWidget() { TimeZone.setDefault(TimeZone.getTimeZone(CET_TIME_ZONE)); - DateTimeWidget dateTimeWidget = prepareDateTimeWidget(2017, 2, 26, 2, 30); + DateTimeWidget dateTimeWidget = prepareDateTimeWidget(2017, 3, 26, 2, 30); /** * We would get crash in this place using old approach {@link org.joda.time.DateTime} instead of @@ -98,15 +101,18 @@ private DateWidget prepareDateWidget(int year, int month, int day) { stub(iFormElementStub.getAdditionalAttribute(anyString(), anyString())).toReturn(null); stub(formEntryPromptStub.getQuestion()).toReturn(questionDefStub); stub(formEntryPromptStub.getFormElement()).toReturn(iFormElementStub); - stub(formEntryPromptStub.getQuestion().getAppearanceAttr()).toReturn("no-calendar"); + DatePickerDialog datePickerDialog = mock(DatePickerDialog.class); DatePicker datePicker = mock(DatePicker.class); - stub(datePicker.getYear()).toReturn(year); - stub(datePicker.getMonth()).toReturn(month); - stub(datePicker.getDayOfMonth()).toReturn(day); + stub(datePickerDialog.getDatePicker()).toReturn(datePicker); + stub(datePickerDialog.getDatePicker().getYear()).toReturn(year); + stub(datePickerDialog.getDatePicker().getMonth()).toReturn(month); + stub(datePickerDialog.getDatePicker().getDayOfMonth()).toReturn(day); DateWidget dateWidget = new DateWidget(RuntimeEnvironment.application, formEntryPromptStub); - Whitebox.setInternalState(dateWidget, "mDatePicker", datePicker); + Whitebox.setInternalState(dateWidget, "mDatePickerDialog", datePickerDialog); + + IAnswerData test = dateWidget.getAnswer(); return dateWidget; } @@ -119,20 +125,19 @@ private DateTimeWidget prepareDateTimeWidget(int year, int month, int day, int h stub(iFormElementStub.getAdditionalAttribute(anyString(), anyString())).toReturn(null); stub(formEntryPromptStub.getQuestion()).toReturn(questionDefStub); stub(formEntryPromptStub.getFormElement()).toReturn(iFormElementStub); - stub(formEntryPromptStub.getQuestion().getAppearanceAttr()).toReturn("no-calendar"); - DatePicker datePicker = mock(DatePicker.class); - stub(datePicker.getYear()).toReturn(year); - stub(datePicker.getMonth()).toReturn(month); - stub(datePicker.getDayOfMonth()).toReturn(day); + DateWidget dateWidget = mock(DateWidget.class); + stub(dateWidget.getYear()).toReturn(year); + stub(dateWidget.getMonth()).toReturn(month); + stub(dateWidget.getDay()).toReturn(day); - TimePicker timePicker = mock(TimePicker.class); - stub(timePicker.getCurrentHour()).toReturn(hour); - stub(timePicker.getCurrentMinute()).toReturn(minute); + TimeWidget timeWidget = mock(TimeWidget.class); + stub(timeWidget.getHour()).toReturn(hour); + stub(timeWidget.getMinute()).toReturn(minute); DateTimeWidget dateTimeWidget = new DateTimeWidget(RuntimeEnvironment.application, formEntryPromptStub); - Whitebox.setInternalState(dateTimeWidget, "mDatePicker", datePicker); - Whitebox.setInternalState(dateTimeWidget, "mTimePicker", timePicker); + Whitebox.setInternalState(dateTimeWidget, "mDateWidget", dateWidget); + Whitebox.setInternalState(dateTimeWidget, "mTimeWidget", timeWidget); return dateTimeWidget; } From 64589aae95fb2e72b80d9ee8f740c651a076b1ac Mon Sep 17 00:00:00 2001 From: grzegorz Date: Wed, 12 Apr 2017 15:53:48 +0200 Subject: [PATCH 19/25] Added calendar back --- .../android/utilities/DateWidgetUtils.java | 74 +++++++++++++++++++ .../collect/android/widgets/DateWidget.java | 19 ++++- 2 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 collect_app/src/main/java/org/odk/collect/android/utilities/DateWidgetUtils.java diff --git a/collect_app/src/main/java/org/odk/collect/android/utilities/DateWidgetUtils.java b/collect_app/src/main/java/org/odk/collect/android/utilities/DateWidgetUtils.java new file mode 100644 index 00000000000..86de67f62ac --- /dev/null +++ b/collect_app/src/main/java/org/odk/collect/android/utilities/DateWidgetUtils.java @@ -0,0 +1,74 @@ +package org.odk.collect.android.utilities; + +import android.util.Log; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CalendarView; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +/** + * The function fixCalendarViewIfJellyBean fixes the Calendar view bug for Android 4.1.2 devices + * + * For more info read the complete solution at this link : http://stackoverflow.com/a/36321828/5479029 + */ + +public class DateWidgetUtils { + + public static void fixCalendarViewIfJellyBean(CalendarView calendarView) { + try { + Object object = calendarView; + Field[] fields = object.getClass().getDeclaredFields(); + for (Field field : fields) { + if (field.getName().equals("mDelegate")) { // the CalendarViewLegacyDelegate instance is stored in this variable + field.setAccessible(true); + object = field.get(object); + break; + } + } + + Field field = object.getClass().getDeclaredField("mDateTextSize"); // text size integer value + field.setAccessible(true); + final int mDateTextSize = (Integer) field.get(object); + + field = object.getClass().getDeclaredField("mListView"); // main ListView + field.setAccessible(true); + Object innerObject = field.get(object); + + Method method = innerObject.getClass().getMethod( + "setOnHierarchyChangeListener", ViewGroup.OnHierarchyChangeListener.class); // we need to set the OnHierarchyChangeListener + method.setAccessible(true); + method.invoke(innerObject, (Object) new ViewGroup.OnHierarchyChangeListener() { + @Override + public void onChildViewAdded(View parent, View child) { // apply text size every time when a new child view is added + try { + Object object = child; + Field[] fields = object.getClass().getDeclaredFields(); + for (Field field : fields) { + if (field.getName().equals("mMonthNumDrawPaint")) { // the paint is stored inside the view + field.setAccessible(true); + object = field.get(object); + Method method = object.getClass(). + getDeclaredMethod("setTextSize", float.class); // finally set text size + method.setAccessible(true); + method.invoke(object, (Object) mDateTextSize); + + break; + } + } + } catch (Exception e) { + Log.e("DateTimeWidget", e.getMessage(), e); + } + } + + @Override + public void onChildViewRemoved(View parent, View child) { + } + }); + } catch (Exception e) { + Log.e("DateTimeWidget", e.getMessage(), e); + } + } + +} diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java index 87c03954947..3440c2737a8 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java @@ -17,11 +17,13 @@ import android.app.DatePickerDialog; import android.content.Context; import android.content.res.Resources; +import android.os.Build; import android.util.TypedValue; import android.view.Gravity; import android.view.View; import android.view.inputmethod.InputMethodManager; import android.widget.Button; +import android.widget.CalendarView; import android.widget.DatePicker; import android.widget.LinearLayout; import android.widget.TableLayout; @@ -33,6 +35,7 @@ import org.joda.time.DateTime; import org.joda.time.LocalDateTime; import org.odk.collect.android.R; +import org.odk.collect.android.utilities.DateWidgetUtils; import java.util.Date; @@ -51,6 +54,7 @@ public class DateWidget extends QuestionWidget { private boolean mHideDay; private boolean mHideMonth; + private boolean mShowCalendar; public DateWidget(Context context, FormEntryPrompt prompt) { super(context, prompt); @@ -62,6 +66,10 @@ public DateWidget(Context context, FormEntryPrompt prompt) { createDatePickerDialog(); addViews(); hideDayFieldIfNotInFormat(); + + if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN) { + DateWidgetUtils.fixCalendarViewIfJellyBean(mDatePickerDialog.getDatePicker().getCalendarView()); + } } private void hideDayFieldIfNotInFormat() { @@ -71,6 +79,13 @@ private void hideDayFieldIfNotInFormat() { } else if ("year".equals(appearance)) { mHideDay = true; mHideMonth = true; + } else if (!"no-calendar".equals(appearance)) { + mHideDay = true; + mShowCalendar = true; + mDatePickerDialog.getDatePicker().setCalendarViewShown(true); + CalendarView cv = mDatePickerDialog.getDatePicker().getCalendarView(); + cv.setShowWeekNumber(false); + mDatePickerDialog.getDatePicker().setSpinnersShown(true); } if (mHideDay) { @@ -101,8 +116,8 @@ public IAnswerData getAnswer() { LocalDateTime ldt = new LocalDateTime() .withYear(mDatePickerDialog.getDatePicker().getYear()) - .withMonthOfYear(mHideMonth ? 1 : mDatePickerDialog.getDatePicker().getMonth() + 1) - .withDayOfMonth(mHideMonth || mHideDay ? 1 : mDatePickerDialog.getDatePicker().getDayOfMonth()) + .withMonthOfYear((!mShowCalendar && mHideMonth) ? 1 : mDatePickerDialog.getDatePicker().getMonth() + 1) + .withDayOfMonth((!mShowCalendar && (mHideMonth || mHideDay)) ? 1 : mDatePickerDialog.getDatePicker().getDayOfMonth()) .withHourOfDay(0) .withMinuteOfHour(0); From 82399be2a7a3d6588033721984bb524523f8a75e Mon Sep 17 00:00:00 2001 From: grzegorz Date: Wed, 12 Apr 2017 15:55:18 +0200 Subject: [PATCH 20/25] Fixed displayed text --- .../odk/collect/android/widgets/DateWidget.java | 16 +--------------- .../odk/collect/android/widgets/TimeWidget.java | 5 +---- 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java index 3440c2737a8..82f87c4a098 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java @@ -181,21 +181,7 @@ private void addViews() { } private void setDate() { - int dayOfMonth = mDatePickerDialog.getDatePicker().getDayOfMonth(); - int monthOfYear = mDatePickerDialog.getDatePicker().getMonth() + 1; - int year = mDatePickerDialog.getDatePicker().getYear(); - - String dayText = dayOfMonth < 10 ? "0" + dayOfMonth : "" + dayOfMonth; - String monthText = monthOfYear < 10 ? "0" + monthOfYear : "" + monthOfYear; - - String appearance = mPrompt.getQuestion().getAppearanceAttr(); - if ("month-year".equals(appearance)) { - mDateTextView.setText(getContext().getString(R.string.date_year_month, monthText, String.valueOf(year))); - } else if ("year".equals(appearance)) { - mDateTextView.setText(String.valueOf(year)); - } else { - mDateTextView.setText(getContext().getString(R.string.full_date, dayText, monthText, String.valueOf(year))); - } + mDateTextView.setText(getAnswer().getDisplayText()); } private void createDatePickerDialog() { diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java index 4f7ad21c61a..e9e28780872 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java @@ -139,10 +139,7 @@ private void setTime(int hourOfDay, int minuteOfHour) { mHourOfDay = hourOfDay; mMinuteOfHour = minuteOfHour; - String hour = mHourOfDay < 10 ? "0" + mHourOfDay : "" + mHourOfDay; - String minute = mMinuteOfHour < 10 ? "0" + mMinuteOfHour : "" + mMinuteOfHour; - - mTimeTextView.setText(getContext().getString(R.string.time, hour, minute)); + mTimeTextView.setText(getAnswer().getDisplayText()); } private void createTimePickerDialog() { From c8333d75a4249c1d79b34811330a19614831500d Mon Sep 17 00:00:00 2001 From: grzegorz Date: Wed, 12 Apr 2017 16:30:02 +0200 Subject: [PATCH 21/25] Fixed bug --- .../org/odk/collect/android/widgets/DateTimeWidget.java | 9 +++++---- .../java/org/odk/collect/android/widgets/DateWidget.java | 4 ++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/DateTimeWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/DateTimeWidget.java index 622ab37586a..b3b928ecae9 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/DateTimeWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/DateTimeWidget.java @@ -62,6 +62,7 @@ public IAnswerData getAnswer() { boolean hideDay = mDateWidget.isDayHidden(); boolean hideMonth = mDateWidget.isMonthHidden(); + boolean showCalendar = mDateWidget.isCalendarShown(); int year = mDateWidget.getYear(); int month = mDateWidget.getMonth(); @@ -71,10 +72,10 @@ public IAnswerData getAnswer() { LocalDateTime ldt = new LocalDateTime() .withYear(year) - .withMonthOfYear(hideMonth ? 1 : month) - .withDayOfMonth(hideMonth || hideDay ? 1 : day) - .withHourOfDay(hideMonth || hideDay ? 0 : hour) - .withMinuteOfHour(hideMonth || hideDay ? 0 : minute) + .withMonthOfYear((!showCalendar && hideMonth) ? 1 : month) + .withDayOfMonth((!showCalendar && (hideMonth || hideDay)) ? 1 : day) + .withHourOfDay((!showCalendar && (hideMonth || hideDay)) ? 0 : hour) + .withMinuteOfHour((!showCalendar && (hideMonth) || hideDay) ? 0 : minute) .withSecondOfMinute(0); ldt = skipDaylightSavingGapIfExists(ldt); diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java index 82f87c4a098..751fabf3132 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java @@ -215,6 +215,10 @@ public boolean isMonthHidden() { return mHideMonth; } + public boolean isCalendarShown() { + return mShowCalendar; + } + public int getYear() { return mDatePickerDialog.getDatePicker().getYear(); } From 6a8b9a768b380dff6a034ae1eab9d7fdd4a34f96 Mon Sep 17 00:00:00 2001 From: grzegorz Date: Wed, 12 Apr 2017 17:42:01 +0200 Subject: [PATCH 22/25] Added custom dialogs --- .../android/widgets/DateTimeWidget.java | 1 - .../collect/android/widgets/DateWidget.java | 16 +++++++++++-- .../collect/android/widgets/TimeWidget.java | 24 ++++++++++++++++--- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/DateTimeWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/DateTimeWidget.java index b3b928ecae9..95c56b3ca82 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/DateTimeWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/DateTimeWidget.java @@ -23,7 +23,6 @@ import org.javarosa.core.model.data.IAnswerData; import org.javarosa.form.api.FormEntryPrompt; -import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.joda.time.LocalDateTime; /** diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java index 751fabf3132..4b43d4f41aa 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java @@ -185,7 +185,7 @@ private void setDate() { } private void createDatePickerDialog() { - mDatePickerDialog = new DatePickerDialog(getContext(), + mDatePickerDialog = new CustomDatePickerDialog(getContext(), new DatePickerDialog.OnDateSetListener() { @Override public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { @@ -193,7 +193,6 @@ public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth setDate(); } }, 0, 0, 0); - mDatePickerDialog.setCustomTitle(new LinearLayout(getContext())); // If there's an answer, use it. if (mPrompt.getAnswerValue() != null) { @@ -230,4 +229,17 @@ public int getMonth() { public int getDay() { return mDatePickerDialog.getDatePicker().getDayOfMonth(); } + + private class CustomDatePickerDialog extends DatePickerDialog { + private String mDialogTitle = getContext().getString(R.string.select_date); + + public CustomDatePickerDialog(Context context, OnDateSetListener listener, int year, int month, int dayOfMonth) { + super(context, listener, year, month, dayOfMonth); + setTitle(mDialogTitle); + } + + public void setTitle(CharSequence title) { + super.setTitle(mDialogTitle); + } + } } diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java index e9e28780872..36616014bc3 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/TimeWidget.java @@ -143,14 +143,13 @@ private void setTime(int hourOfDay, int minuteOfHour) { } private void createTimePickerDialog() { - mTimePickerDialog = new TimePickerDialog(getContext(), + mTimePickerDialog = new CustomTimePickerDialog(getContext(), new TimePickerDialog.OnTimeSetListener() { @Override public void onTimeSet(TimePicker view, int hourOfDay, int minuteOfHour) { setTime(hourOfDay, minuteOfHour); } - }, 0, 0, DateFormat.is24HourFormat(getContext())); - mTimePickerDialog.setCustomTitle(new LinearLayout(getContext())); + }, 0, 0); // If there's an answer, use it. if (mPrompt.getAnswerValue() != null) { @@ -171,4 +170,23 @@ public int getHour() { public int getMinute() { return mMinuteOfHour; } + + private class CustomTimePickerDialog extends TimePickerDialog implements TimePickerDialog.OnTimeSetListener { + private String mDialogTitle = getContext().getString(R.string.select_time); + + public CustomTimePickerDialog(Context context, OnTimeSetListener callBack, int hour, int minute) { + super(context, callBack, hour, minute, DateFormat.is24HourFormat(context)); + setTitle(mDialogTitle); + } + + public void setTitle(CharSequence title) { + super.setTitle(mDialogTitle); + } + + @Override + public void onTimeSet(TimePicker view, int hourOfDay, int minute) { + mHourOfDay = hourOfDay; + mMinuteOfHour = minute; + } + } } From afc34e9c8dc910b94c38c19bd7694ac2634f83c7 Mon Sep 17 00:00:00 2001 From: grzegorz Date: Wed, 12 Apr 2017 18:12:13 +0200 Subject: [PATCH 23/25] Fixed bugs and test --- .../org/odk/collect/android/widgets/DateTimeWidget.java | 6 ++++-- collect_app/src/main/res/values/untranslated.xml | 3 --- .../odk/collect/android/utilities/DaylightSavingTest.java | 6 ++---- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/DateTimeWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/DateTimeWidget.java index 95c56b3ca82..a4ca583e6ad 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/DateTimeWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/DateTimeWidget.java @@ -51,7 +51,9 @@ public DateTimeWidget(Context context, FormEntryPrompt prompt) { LinearLayout linearLayout = new LinearLayout(getContext()); linearLayout.setOrientation(LinearLayout.VERTICAL); linearLayout.addView(mDateWidget); - linearLayout.addView(mTimeWidget); + if (mDateWidget.isCalendarShown() || !mDateWidget.isDayHidden()) { + linearLayout.addView(mTimeWidget); + } addAnswerView(linearLayout); } @@ -74,7 +76,7 @@ public IAnswerData getAnswer() { .withMonthOfYear((!showCalendar && hideMonth) ? 1 : month) .withDayOfMonth((!showCalendar && (hideMonth || hideDay)) ? 1 : day) .withHourOfDay((!showCalendar && (hideMonth || hideDay)) ? 0 : hour) - .withMinuteOfHour((!showCalendar && (hideMonth) || hideDay) ? 0 : minute) + .withMinuteOfHour((!showCalendar && (hideMonth || hideDay)) ? 0 : minute) .withSecondOfMinute(0); ldt = skipDaylightSavingGapIfExists(ldt); diff --git a/collect_app/src/main/res/values/untranslated.xml b/collect_app/src/main/res/values/untranslated.xml index 194cff23a99..55dd397c0a0 100644 --- a/collect_app/src/main/res/values/untranslated.xml +++ b/collect_app/src/main/res/values/untranslated.xml @@ -15,8 +15,5 @@ https://opendatakit.appspot.com /formList /submission - %1$s:%2$s - %1$s/%2$s/%3$s - %1$s/%2$s diff --git a/collect_app/src/test/java/org/odk/collect/android/utilities/DaylightSavingTest.java b/collect_app/src/test/java/org/odk/collect/android/utilities/DaylightSavingTest.java index 86d746eab56..5b26a857b16 100644 --- a/collect_app/src/test/java/org/odk/collect/android/utilities/DaylightSavingTest.java +++ b/collect_app/src/test/java/org/odk/collect/android/utilities/DaylightSavingTest.java @@ -17,11 +17,9 @@ import android.app.DatePickerDialog; import android.widget.DatePicker; -import android.widget.TimePicker; import org.javarosa.core.model.IFormElement; import org.javarosa.core.model.QuestionDef; -import org.javarosa.core.model.data.IAnswerData; import org.javarosa.form.api.FormEntryPrompt; import org.junit.After; import org.junit.Before; @@ -101,6 +99,7 @@ private DateWidget prepareDateWidget(int year, int month, int day) { stub(iFormElementStub.getAdditionalAttribute(anyString(), anyString())).toReturn(null); stub(formEntryPromptStub.getQuestion()).toReturn(questionDefStub); stub(formEntryPromptStub.getFormElement()).toReturn(iFormElementStub); + stub(formEntryPromptStub.getQuestion().getAppearanceAttr()).toReturn("no-calendar"); DatePickerDialog datePickerDialog = mock(DatePickerDialog.class); DatePicker datePicker = mock(DatePicker.class); @@ -112,8 +111,6 @@ private DateWidget prepareDateWidget(int year, int month, int day) { DateWidget dateWidget = new DateWidget(RuntimeEnvironment.application, formEntryPromptStub); Whitebox.setInternalState(dateWidget, "mDatePickerDialog", datePickerDialog); - IAnswerData test = dateWidget.getAnswer(); - return dateWidget; } @@ -125,6 +122,7 @@ private DateTimeWidget prepareDateTimeWidget(int year, int month, int day, int h stub(iFormElementStub.getAdditionalAttribute(anyString(), anyString())).toReturn(null); stub(formEntryPromptStub.getQuestion()).toReturn(questionDefStub); stub(formEntryPromptStub.getFormElement()).toReturn(iFormElementStub); + stub(formEntryPromptStub.getQuestion().getAppearanceAttr()).toReturn("no-calendar"); DateWidget dateWidget = mock(DateWidget.class); stub(dateWidget.getYear()).toReturn(year); From 609f29d6949b065d3d39ea33602d2fc23332dbf2 Mon Sep 17 00:00:00 2001 From: Grzegorz Orczykowski Date: Fri, 14 Apr 2017 09:05:03 +0200 Subject: [PATCH 24/25] Update strings.xml --- collect_app/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collect_app/src/main/res/values/strings.xml b/collect_app/src/main/res/values/strings.xml index fe6aed4da91..798b901889b 100644 --- a/collect_app/src/main/res/values/strings.xml +++ b/collect_app/src/main/res/values/strings.xml @@ -499,6 +499,6 @@ Device ID Subscriber ID SIM serial number -Select date +Select date Select time From d623d86c969f74eac63da5693e31cebc73ad09a9 Mon Sep 17 00:00:00 2001 From: grzegorz Date: Fri, 14 Apr 2017 11:01:12 +0200 Subject: [PATCH 25/25] Changes for calendar appearance --- .../collect/android/widgets/DateWidget.java | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java b/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java index 4b43d4f41aa..6e367a50d80 100644 --- a/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java +++ b/collect_app/src/main/java/org/odk/collect/android/widgets/DateWidget.java @@ -25,6 +25,7 @@ import android.widget.Button; import android.widget.CalendarView; import android.widget.DatePicker; +import android.widget.HorizontalScrollView; import android.widget.LinearLayout; import android.widget.TableLayout; import android.widget.TextView; @@ -64,8 +65,8 @@ public DateWidget(Context context, FormEntryPrompt prompt) { createDateButton(); createDateTextView(); createDatePickerDialog(); - addViews(); hideDayFieldIfNotInFormat(); + addViews(); if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN) { DateWidgetUtils.fixCalendarViewIfJellyBean(mDatePickerDialog.getDatePicker().getCalendarView()); @@ -173,11 +174,20 @@ private void createDateTextView() { } private void addViews() { - LinearLayout linearLayout = new LinearLayout(getContext()); - linearLayout.setOrientation(LinearLayout.VERTICAL); - linearLayout.addView(mDateButton); - linearLayout.addView(mDateTextView); - addAnswerView(linearLayout); + if (mShowCalendar) { + HorizontalScrollView mScrollView = new HorizontalScrollView(getContext()); + LinearLayout ll = new LinearLayout(getContext()); + ll.addView(mDatePickerDialog.getDatePicker()); + ll.setPadding(10, 10, 10, 10); + mScrollView.addView(ll); + addAnswerView(mScrollView); + } else { + LinearLayout linearLayout = new LinearLayout(getContext()); + linearLayout.setOrientation(LinearLayout.VERTICAL); + linearLayout.addView(mDateButton); + linearLayout.addView(mDateTextView); + addAnswerView(linearLayout); + } } private void setDate() {