How is it possible to get a DatePickerDialog with Holo Light theme?
When creating a DatePickerDialog as follows:
DatePickerDialog dpd = new DatePickerDialog(new ContextThemeWrapper(this,
android.R.style.Theme_Holo_Light_Dialog_NoActionBar),
new DateListener(v), mTime.year, mTime.month, mTime.monthDay);
or with theme android.R.style.Theme_Holo_Light or android.R.style.Theme_Holo_Light_Dialog, I get a date picker with a standard title and standard buttons. I tried to use a custom theme with a holo light parent too, but it didn't work either. It seems to work with theme android.R.style.Theme_Holo, but the result is a dark background (as expected), but I would like to have a light one.
The application's android.jar is of version 14, the application is running on a divice with android version 3.2.
I have seen an example here: http://as400samplecode.blogspot.com/2011/10/android-datepickerdialog.html, which shows a DatePickerDialog with the holo light theme, the way I would like to have it. I don't know why it doesn't work with my setup.
Thank you for help.
The DatePickerDialog has a constructor which accepts a theme
DatePickerDialog(Context context, int theme, DatePickerDialog.OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth)
just update your code to include the style you want without the need for a ContextThemeWrapper
DatePickerDialog dpd = new DatePickerDialog(this,
android.R.style.Theme_Holo_Light_Dialog_NoActionBar,
new DateListener(v), mTime.year, mTime.month, mTime.monthDay);
It's working for me that way.
Read this Android DatePickerDialog example code which includes how to use different Themes in DatePickerDialog.
Here is the such one.
DatePickerDialog Constructor which support to define Theme.
final Calendar c = Calendar.getInstance();
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH);
int day = c.get(Calendar.DAY_OF_MONTH);
return new DatePickerDialog(getActivity(), AlertDialog.THEME_HOLO_DARK, this, year, month, day);
For Material style this worked for me:
int datePickerThemeResId = 0;
if (android.os.Build.VERSION.SDK_INT >= 21) {
datePickerThemeResId = android.R.style.Theme_Material_Light_Dialog;
}
new DatePickerDialog(
context,
datePickerThemeResId,
(view, year, month, dayOfMonth) -> {},
year,
month,
day
).show();
Related
I am building an app that uses a DatePickerDialog to allow the user to select their birthdate. Here's the code that loads the dialog right now:
private void selectBirthdate() {
int year, month, day;
if (mBirthDate == null) {
year = DEF_YEAR;
month = DEF_MON;
day = DEF_DAY;
}
else {
year = mBirthDate.get(Calendar.YEAR);
month = mBirthDate.get(Calendar.MONTH);
day = mBirthDate.get(Calendar.DAY_OF_MONTH);
}
new DatePickerDialog(
getActivity(),
new DatePickerDialog.OnDateSetListener() {
#Override
public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
mBirthDate = new GregorianCalendar();
mBirthDate.set(Calendar.YEAR, year);
mBirthDate.set(Calendar.MONTH, month);
mBirthDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
if (mTxtBirthDate != null) {
mTxtBirthDate.setText(mBirthDateFormat.format(mBirthDate.getTime()));
}
}
},
year,
month,
day
).show();
}
And here's what the dialog looks like when I load it:
However, they want to be able to use the old-style spinner DatePicker, because in the new Calendar view, it's not always obvious to the user that they can change the year. So I have been studying up on the topic, and according to what I have read, it should be possible to use themes to force the DatePickerDialog into Spinner mode. So here's what I've done.
First, I added the following to my styles.xml:
(Sorry for the screenshot. Apparently SO's parser can't handle XML.)
Then, I update the DatePickerDialog constructor to use my new style:
new DatePickerDialog(
getActivity(),
R.style.MyDialogTheme,
new DatePickerDialog.OnDateSetListener() {
#Override
public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
mBirthDate = new GregorianCalendar();
mBirthDate.set(Calendar.YEAR, year);
mBirthDate.set(Calendar.MONTH, month);
mBirthDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
if (mTxtBirthDate != null) {
mTxtBirthDate.setText(mBirthDateFormat.format(mBirthDate.getTime()));
}
}
},
year,
month,
day
).show();
Now, when I load the dialog it looks like this:
Clearly something has changed; the dialog has a darker theme. But it's not doing what I want. It's still displaying the calendar view instead of the spinner view. Any idea what I might have missed?
Here is what worked for me:
1) Create these two styles in your style.xml
<style name="MySpinnerDatePickerStyle" parent="android:Theme.Material.Dialog">
<item name="android:datePickerStyle">#style/MySpinnerDatePicker</item>
</style>
<style name="MySpinnerDatePicker" parent="android:Widget.Material.DatePicker">
<item name="android:datePickerMode">spinner</item>
</style>
2) Set "MySpinnerDatePickerStyle" as your style in your new DatePickerDialog
DatePickerDialog datePickerDialog = new DatePickerDialog(myContext, R.style.MySpinnerDatePickerStyle, date, myCalendar
.get(Calendar.YEAR), myCalendar.get(Calendar.MONTH),
myCalendar.get(Calendar.DAY_OF_MONTH));
Hope this works for you..
Note: I am still trying to figure out how to style the spinner by changing color and text color
Similarly as #Abuzaid said, inside your AppTheme style, add the android:datePickerStyle item as shown in this AppTheme example below:
<!-- Example of a Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorPrimary</item>
<!-- !Important! Add this to force the use of the Spinner mode -->
<item name="android:datePickerStyle">#style/myDatePickerStyle</item>
</style>
Add this style to your styles.xml (inside the values-v21 folder, becouse this option is available only for api 21+)
<style name="myDatePickerStyle" parent="android:Widget.Material.DatePicker">
<item name="android:datePickerMode">spinner</item>
</style>
For Android version < 21, the spinner mode is the default. For 21+ the calendar mode is the new default mode.
In this case you can omit to specify the dialog theme becouse it will be inferred by the AppTheme that we have. For example: (With Java 8 lambda)
final Calendar cal = Calendar.getInstance();
final DatePickerDialog.OnDateSetListener dateSelectedListener = (view, year, monthOfYear, dayOfMonth) -> {
cal.set(Calendar.YEAR, year);
cal.set(Calendar.MONTH, monthOfYear+1);
cal.set(Calendar.DAY_OF_MONTH, dayOfMonth);
};
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH);
int day = cal.get(Calendar.DAY_OF_MONTH);
DatePickerDialog dp= new DatePickerDialog(context, dateSelectedListener, year, month, day);
Reference: https://developer.android.com/reference/android/app/DatePickerDialog
Hope it can help! :)
Using the styles mentioned in the other answer to get the spinner only works on stock (or close to stock) Android devices, such as Pixel, Motorola, OnePlus, etc.
I made the mistake of testing on these devices only, and to my surprise, Samsung users were still complaining about the other picker, where they couldn't find how to change the birthdate year without having to scroll month by month.
The only cross device solution is using a library, that way you are sure you get the same spinner picker regardless of the underlying OS. I my case, I used SpinnerDatePicker, which is a pretty straightforward replacement for the native picker.
Simple solution with Material Componente
<style name="SpinnerDatePickerDialogTheme" parent="ThemeOverlay.MaterialComponents.Dialog">
<item name="android:datePickerStyle">#style/DatePickerStyle</item>
<item name="colorControlNormal">#color/teal_200</item>
</style>
<style name="DatePickerStyle" parent="#android:style/Widget.Material.Light.DatePicker">
<item name="android:datePickerMode">spinner</item>
</style>
For some reason ThemeOverlay.MaterialComponents.Dialog.Alert is not working with darkmode
Only Samsung s7 run android 7.x
Here my code
DatePickerDialog datePickerDialog = new DatePickerDialog(activity
,new DatePickerDialog.OnDateSetListener() {
#Override
public void onDateSet(DatePicker view, int year
, int monthOfYear
, int dayOfMonth) {
listener.onDateSet(year, monthOfYear, dayOfMonth);
}
}
,c.get(Calendar.YEAR)
, c.get(Calendar.MONTH)
, c.get(Calendar.DAY_OF_MONTH));
int firstDayOfWeek = TimeUtils.getFirstDayOfWeek(activity);
datePickerDialog.getDatePicker().setFirstDayOfWeek(firstDayOfWeek);
datePickerDialog.show();
Someone advise me how to solve this problem?
Thanks!
You don't set custom style for dialog so this normal(default style). If you want "fix" this "bug" you must create custom style dialog.
For me works fine on the same device, I extend DialogFrament in my app and use code like this:
public static class DatePickerFragment extends DialogFragment
implements DatePickerDialog.OnDateSetListener {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the current date as the default date in the picker
final Calendar c = Calendar.getInstance();
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH);
int day = c.get(Calendar.DAY_OF_MONTH);
// Create a new instance of DatePickerDialog and return it
return new DatePickerDialog(getActivity(), this, year, month, day);
}
public void onDateSet(DatePicker view, int year, int month, int day) {
// Do something with the date chosen by the user
}
}
and then use this method on the view I need to open the dialog:
public void showDatePickerDialog(View v) {
DialogFragment newFragment = new DatePickerFragment();
newFragment.show(getSupportFragmentManager(), "datePicker");
}
Try to implement this or follow the guide on the developer site:
https://developer.android.com/guide/topics/ui/controls/pickers.html
The problem is that the actual implementation of DatePickerDialog's UI is device specific and it can have some issues.
I've got similar issues on devices with the screen width smaller than 360dp. Fixed this by using THEME_HOLO_LIGHT theme.
DatePickerDialog has a constructor which accepts a theme:
DatePickerDialog(Context context, int theme, DatePickerDialog.OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth)
You may use one of the following:
AlertDialog.THEME_DEVICE_DEFAULT_DARK
AlertDialog.THEME_DEVICE_DEFAULT_LIGHT
AlertDialog.THEME_HOLO_DARK
AlertDialog.THEME_HOLO_LIGHT
AlertDialog.THEME_TRADITIONAL
One of my features require the user to select a month and year, so the following is the method which will pop up the first attached image (d/m/y).
final Calendar c = Calendar.getInstance();
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH);
int day = c.get(Calendar.DAY_OF_MONTH);
DatePickerDialog dp = new DatePickerDialog(getActivity(), android.R.style.Theme_Holo_Light_Dialog_MinWidth,
new DatePickerDialog.OnDateSetListener() {
#Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
//Check if selected month/year is in future of today.
}
}, year, month, day);
dp.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
dp.setTitle("Set Monthly Overview");
dp.show();
However, i do NOT require the date. How can i disable user from selecting it, or best of all, to even not display the date option there?
What I wish to achieve is something like the following image in the best case scenario.
Refer "Android DatePicker change to only Month and Year" which will help you just display month and year in the datepicker. Hope this helps.
I am triggering a DatePickerDialog, It's working and showing fine till api 22 (Android 5.1), I am setting mix and max dates on it (min = current date, max = 1 month starting from current date), but It's just showing current date in Api 23, I attached code and images.
///////////////////////////////datepickerdialog///////////////////////////////
public static class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener{
#Override
public Dialog onCreateDialog(Bundle savedInstanceState){
final Calendar calendar = Calendar.getInstance();
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int day = calendar.get(Calendar.DAY_OF_MONTH);
/*
Create a DatePickerDialog using Theme.
DatePickerDialog(Context context, int theme, DatePickerDialog.OnDateSetListener listener,
int year, int monthOfYear, int dayOfMonth)
*/
// DatePickerDialog THEME_DEVICE_DEFAULT_LIGHT
DatePickerDialog dpd = new DatePickerDialog(getActivity(),this,year,month,day);
if (Build.VERSION.SDK_INT < 22){
dpd.getDatePicker().setCalendarViewShown(true);
dpd.getDatePicker().setSpinnersShown(false);
dpd.getDatePicker().getCalendarView().setShowWeekNumber(false);
}
calendar.setTimeInMillis(calendar.getTimeInMillis());
long mindate = calendar.getTime().getTime();
calendar.add(Calendar.MONTH, 1);
long maxdate = calendar.getTime().getTime();
dpd.getDatePicker().setMinDate(mindate);
dpd.getDatePicker().setMaxDate(maxdate);
dpd.getDatePicker().setMinDate(mindate);
if(Build.VERSION.SDK_INT < 23){
dpd.setTitle("");
}
// Return the DatePickerDialog
return dpd;
}
#SuppressLint("SimpleDateFormat")
public void onDateSet(DatePicker view, int year, int month, int day){
// Do something with the chosen date
month++;
evento_fecha = year+"-"+month+"-"+day;
month--;
datetime.set(Calendar.YEAR, year);
datetime.set(Calendar.MONTH, month);
datetime.set(Calendar.DAY_OF_MONTH, day);
SimpleDateFormat mSDF = new SimpleDateFormat("dd/MM/yyyy");
fecha = mSDF.format(datetime.getTime());
//fecha_seleccionada.setText(dia+"/"+mes+"/"+year);
fecha_seleccionada.setText(fecha);
}
}
ANSWER 1: Results
DatePicker / DatePickerDialog not appearing properly on Android Marshmallow / API 23 is a theme issue. I suggest, instead of using default theme or writing custom styles, instantiate the DatePickerDialog using 'theme' option:
DatePickerDialog(Context context, int theme, DatePickerDialog.OnDateSetListener listener, int year, int monthOfYear, int dayOfMonth)
API 23 onwards, Material theme should be used for the dialog. Use android.R.style.Theme_Material_Light_Dialog_Alert for the theme parameter.
For Xamarin Android - use Android.Resource.Style.ThemeMaterialLightDialogAlert.
I was using this style in my theme:
<style name="AppTheme" parent="Theme.AppCompat.Light">
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
<item name="colorPrimary">#color/green_sheet</item>
<item name="android:textColorPrimary">#color/textColorPrimary</item>
<item name="android:textAllCaps">false</item>
</style>
The textColorPrimary property was showing all days numbers in white, I used this property in order to set the action bar text to white. I was wrong because I had to use Theme.AppCompat.Light.DarkActionBar for this purpose, so I changed my theme style to this:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
<item name="colorPrimary">#color/green_sheet</item>
<item name="android:textAllCaps">false</item>
</style>
and the result was as expected.
In your DatePicker you have set MinDate to currentTimeMillis() and in your MaxDate you have add 1 MONTH to your Calendar.
Just simple use this code.
public class MainActivity extends Activity {
int mYear, mMonth, mDay;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Calendar c = Calendar.getInstance();
mYear = c.get(Calendar.YEAR);
mMonth = c.get(Calendar.MONTH);
mDay = c.get(Calendar.DAY_OF_MONTH);
final TextView textView = (TextView)findViewById(R.id.textview_totalStone);
textView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DatePickerDialog dpd = new DatePickerDialog(MainActivity.this,
new DatePickerDialog.OnDateSetListener() {
#Override
public void onDateSet(DatePicker view, int year, int month, int day) {
c.set(year, month, day);
String date = new SimpleDateFormat("MM/dd/yyyy").format(c.getTime());
textView.setText(date);
mYear = c.get(Calendar.YEAR);
mMonth = c.get(Calendar.MONTH);
mDay = c.get(Calendar.DAY_OF_MONTH);
}
}, mYear, mMonth, mDay);
dpd.getDatePicker().setMinDate(System.currentTimeMillis());
Calendar d = Calendar.getInstance();
d.add(Calendar.MONTH,1);
dpd.getDatePicker().setMaxDate(d.getTimeInMillis());
dpd.show();
}
});
}
In my DatePicker I have Date June 25 and it select and as your requirement you have MaxDate 1 Month it's show in ScreenShot.
ScreenShot : 1
ScreenShot : 2
Update :
Replace your this code
calendar.setTimeInMillis(calendar.getTimeInMillis());
long mindate = calendar.getTime().getTime();
dpd.getDatePicker().setMinDate(mindate);
with this
dpd.getDatePicker().setMinDate(System.currentTimeMillis());
When i am running my code in android 3.2 and android 4.0.3, it shows different date pickers..i want date picker as a wheeler like 1st image..i know 2.3.3 shows old pickers..But i don't know why i am getting older one in 4.0.3 which is giving new in 3.2. It happened same with Number Picker also.
here is my code:
private DatePickerDialog.OnDateSetListener mDateSetListener = new DatePickerDialog.OnDateSetListener() {
public void onDateSet(DatePicker view, int year, int monthOfYear,
int dayOfMonth) {
mYear = year;
mMonth = monthOfYear;
mDay = dayOfMonth;
if (picker == 1) {
final long lDate = mDay;
dateStart.set(Calendar.YEAR, mYear);
dateStart.set(Calendar.MONTH, mMonth);
dateStart.set(Calendar.DATE, mDay);
Log.d("startdate", "" + dateStart);
if (lDate != -1) {
UpdateStartDateTimeView();
return;
}
}
updateDisplay();
}
};
If you use the native picker, automatically Android will choose the corresponding to the current version. You can only ensure that a unique dialog is presented regardless Android version by creating a custom Dialog. Thus, you need to see if the unique picker worths the effort of designing a custom one..
The DatePickerDialog is having a constructor which accepts a theme
DatePickerDialog(Context context, int theme, DatePickerDialog.OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth)
Just update ur code with
for light holo theme
DatePickerDialog datePickerDialog = new DatePickerDialog(this,
android.R.style.Theme_Holo_Light_Dialog_NoActionBar,
new DateListener(v), mTime.year, mTime.month, mTime.monthDay);
or
for dark holo theme
DatePickerDialog datePickerDialog = new DatePickerDialog(this,
android.R.style.Theme_Holo__Dialog_NoActionBar,
new DateListener(v), mTime.year, mTime.month, mTime.monthDay);
If I understand you right, you're getting an old dialog style in Andoid version above 4. I had this problem when I set STYLE_NO_FRAME for dialog fragment. In this case date picker has always old design, and I don't know why it is so. If you want to get always modern UI, be sure you set STYLE_NORMAL to your dialog fragment. For do this you need to add following line in OnCreate callback method of the dialog fragment.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NORMAL, 0);
}