Skip to content

Commit

Permalink
[Android] Add TimePicker modes
Browse files Browse the repository at this point in the history
  • Loading branch information
Kerumen committed Sep 8, 2017
1 parent 30087f9 commit 4e58d51
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ class TimePickerAndroid {
* * `is24Hour` (boolean) - If `true`, the picker uses the 24-hour format. If `false`,
* the picker shows an AM/PM chooser. If undefined, the default for the current locale
* is used.
* * `mode` (`enum('clock', 'spinner', 'default')`) - set the time picker mode
* - 'clock': Show a time picker in clock mode.
* - 'spinner': Show a time picker in spinner mode.
* - 'default': Show a default time picker based on Android versions.
*
* Returns a Promise which will be invoked an object containing `action`, `hour` (0-23),
* `minute` (0-59) if the user picked a time. If the user dismissed the dialog, the Promise will
Expand Down
22 changes: 21 additions & 1 deletion RNTester/js/TimePickerAndroidExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ class TimePickerAndroidExample extends React.Component {
presetMinute: 4,
presetText: 'pick a time, default: 4:04AM',
simpleText: 'pick a time',
clockText: 'pick a time',
spinnerText: 'pick a time',
defaultText: 'pick a time',
};

showPicker = async (stateKey, options) => {
Expand Down Expand Up @@ -60,6 +63,24 @@ class TimePickerAndroidExample extends React.Component {
<Text style={styles.text}>{this.state.simpleText}</Text>
</TouchableWithoutFeedback>
</RNTesterBlock>
<RNTesterBlock title="Simple clock time picker">
<TouchableWithoutFeedback
onPress={this.showPicker.bind(this, 'clock', {mode: 'clock'})}>
<Text style={styles.text}>{this.state.clockText}</Text>
</TouchableWithoutFeedback>
</RNTesterBlock>
<RNTesterBlock title="Simple spinner time picker">
<TouchableWithoutFeedback
onPress={this.showPicker.bind(this, 'spinner', {mode: 'spinner'})}>
<Text style={styles.text}>{this.state.spinnerText}</Text>
</TouchableWithoutFeedback>
</RNTesterBlock>
<RNTesterBlock title="Simple default time picker">
<TouchableWithoutFeedback
onPress={this.showPicker.bind(this, 'default', {mode: 'default'})}>
<Text style={styles.text}>{this.state.defaultText}</Text>
</TouchableWithoutFeedback>
</RNTesterBlock>
<RNTesterBlock title="Time picker with pre-set time">
<TouchableWithoutFeedback
onPress={this.showPicker.bind(this, 'preset', {
Expand All @@ -69,7 +90,6 @@ class TimePickerAndroidExample extends React.Component {
<Text style={styles.text}>{this.state.presetText}</Text>
</TouchableWithoutFeedback>
</RNTesterBlock>

<RNTesterBlock title="Time picker with 24-hour time format">
<TouchableWithoutFeedback
onPress={this.showPicker.bind(this, 'isoFormat', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,22 @@

package com.facebook.react.modules.timepicker;

import javax.annotation.Nullable;

import java.util.Calendar;

import android.app.Dialog;
import android.app.DialogFragment;
import android.app.TimePickerDialog;
import android.app.TimePickerDialog.OnTimeSetListener;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnDismissListener;
import android.os.Build;
import android.os.Bundle;
import android.text.format.DateFormat;

import java.util.Calendar;
import java.util.Locale;

import javax.annotation.Nullable;

@SuppressWarnings("ValidFragment")
public class TimePickerDialogFragment extends DialogFragment {

Expand All @@ -44,6 +47,11 @@ public Dialog onCreateDialog(Bundle savedInstanceState) {
int minute = now.get(Calendar.MINUTE);
boolean is24hour = DateFormat.is24HourFormat(activityContext);

TimePickerMode mode = TimePickerMode.DEFAULT;
if (args != null && args.getString(TimePickerDialogModule.ARG_MODE, null) != null) {
mode = TimePickerMode.valueOf(args.getString(TimePickerDialogModule.ARG_MODE).toUpperCase(Locale.US));
}

if (args != null) {
hour = args.getInt(TimePickerDialogModule.ARG_HOUR, now.get(Calendar.HOUR_OF_DAY));
minute = args.getInt(TimePickerDialogModule.ARG_MINUTE, now.get(Calendar.MINUTE));
Expand All @@ -52,12 +60,43 @@ public Dialog onCreateDialog(Bundle savedInstanceState) {
DateFormat.is24HourFormat(activityContext));
}

return new DismissableTimePickerDialog(
activityContext,
onTimeSetListener,
hour,
minute,
is24hour);
TimePickerDialog dialog = new DismissableTimePickerDialog(
activityContext,
onTimeSetListener,
hour,
minute,
is24hour
);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (mode == TimePickerMode.CLOCK) {
dialog = new DismissableTimePickerDialog(
activityContext,
activityContext.getResources().getIdentifier(
"ClockTimePickerDialog",
"style",
activityContext.getPackageName()
),
onTimeSetListener,
hour,
minute,
is24hour
);
} else if (mode == TimePickerMode.SPINNER) {
dialog = new DismissableTimePickerDialog(
activityContext,
activityContext.getResources().getIdentifier(
"SpinnerTimePickerDialog",
"style",
activityContext.getPackageName()
),
onTimeSetListener,
hour,
minute,
is24hour
);
}
}
return dialog;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@

package com.facebook.react.modules.timepicker;

import javax.annotation.Nullable;

import android.app.Activity;
import android.app.DialogFragment;
import android.app.FragmentManager;
Expand All @@ -31,6 +29,8 @@
import com.facebook.react.common.annotations.VisibleForTesting;
import com.facebook.react.module.annotations.ReactModule;

import javax.annotation.Nullable;

/**
* {@link NativeModule} that allows JS to show a native time picker dialog and get called back when
* the user selects a time.
Expand All @@ -46,6 +46,7 @@ public class TimePickerDialogModule extends ReactContextBaseJavaModule {
/* package */ static final String ARG_HOUR = "hour";
/* package */ static final String ARG_MINUTE = "minute";
/* package */ static final String ARG_IS24HOUR = "is24Hour";
/* package */ static final String ARG_MODE = "mode";
/* package */ static final String ACTION_TIME_SET = "timeSetAction";
/* package */ static final String ACTION_DISMISSED = "dismissedAction";

Expand Down Expand Up @@ -148,6 +149,9 @@ private Bundle createFragmentArguments(ReadableMap options) {
if (options.hasKey(ARG_IS24HOUR) && !options.isNull(ARG_IS24HOUR)) {
args.putBoolean(ARG_IS24HOUR, options.getBoolean(ARG_IS24HOUR));
}
if (options.hasKey(ARG_MODE) && !options.isNull(ARG_MODE)) {
args.putString(ARG_MODE, options.getString(ARG_MODE));
}
return args;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/

package com.facebook.react.modules.timepicker;


public enum TimePickerMode {
CLOCK,
SPINNER,
DEFAULT
}
18 changes: 17 additions & 1 deletion ReactAndroid/src/main/res/shell/values/styles.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
<item name="android:datePickerMode">spinner</item>
</style>


<style name="CalendarDatePickerDialog" parent="Theme.AppCompat.Light.Dialog" tools:targetApi="lollipop">
<item name="android:datePickerStyle">@style/CalendarDatePickerStyle</item>
</style>
Expand All @@ -28,4 +27,21 @@
<item name="android:datePickerMode">calendar</item>
</style>


<style name="ClockTimePickerDialog" parent="Theme.AppCompat.Light.Dialog" tools:targetApi="lollipop">
<item name="android:timePickerStyle">@style/ClockTimePickerStyle</item>
</style>

<style name="ClockTimePickerStyle" parent="android:Widget.Material.Light.TimePicker" tools:targetApi="lollipop">
<item name="android:timePickerMode">clock</item>
</style>

<style name="SpinnerTimePickerDialog" parent="Theme.AppCompat.Light.Dialog" tools:targetApi="lollipop">
<item name="android:timePickerStyle">@style/SpinnerTimePickerStyle</item>
</style>

<style name="SpinnerTimePickerStyle" parent="android:Widget.Material.Light.TimePicker" tools:targetApi="lollipop">
<item name="android:timePickerMode">spinner</item>
</style>

</resources>

0 comments on commit 4e58d51

Please sign in to comment.