Can anybody tell how to display year only in date picker in android
Thanks
You could also use some simple reflection to hide the day and month NumberPicker
s of a DatePicker
widget. Do note that this may stop working if Google decides to rename the member field names. Also, this approach of course makes sense when using android:datePickerMode="spinner".
// inflate DatePicker, or e.g. get it from a DatePickerDialog:
DatePicker datepicker = ...
// pre-Honeycomb fields:
findAndHideField(datepicker, "mDayPicker");
findAndHideField(datepicker, "mMonthPicker");
// Honeycomb(+) fields:
findAndHideField(datepicker, "mDaySpinner");
findAndHideField(datepicker, "mMonthSpinner");
// Lollipop(+) fields (wrapped in a delegate):
final Object mDatePickerDelegate = findFieldInstance(picker, "mDelegate");
findAndHideField(mDatePickerDelegate, "mDaySpinner");
findAndHideField(mDatePickerDelegate, "mMonthSpinner");
/** find a member field by given name and hide it */
private static void findAndHideField(Object object, String name) {
try {
final Field field = object.getClass().getDeclaredField(name);
field.setAccessible(true);
final View fieldInstance = (View) field.get(object);
fieldInstance.setVisibility(View.GONE);
} catch (Exception e) {
e.printStackTrace();
}
}
/* find a member field by given name and return its instance value */
private static Object findFieldInstance(DatePicker datepicker, String name) {
try {
final Field field = DatePicker.class.getDeclaredField(name);
field.setAccessible(true);
return field.get(datepicker);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
Update: Added code illustrating how to make this approach work with Android 'Lollipop' 5.0 (API 21+).
Disclaimer: I cannot stress enough that this is hacky solution that may stop working with any framework update (as it did when Android 3.0 was first introduced, and again with Android 5.0).
private void showBirthDayPicker() {
int year = calendar.get(Calendar.YEAR);
final Dialog birthDayDialog = new Dialog(this);
birthDayDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
birthDayDialog.setContentView(R.layout.dialog_birthday);
Button okBtn = birthDayDialog.findViewById(R.id.btn_ok);
Button cancelBtn = birthDayDialog.findViewById(R.id.btn_cancel);
final NumberPicker np = birthDayDialog.findViewById(R.id.birthdayPicker);
np.setMinValue(year - 100);
np.setMaxValue(year - 15);
np.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);
setDivider(np, android.R.color.white);
np.setWrapSelectorWheel(false);
np.setValue(year-20);
np.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
@Override
public void onValueChange(NumberPicker numberPicker, int i, int i1) {
}
});
okBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
edtBirthDay.setText(String.valueOf(np.getValue()));
birthDayDialog.dismiss();
}
});
cancelBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
birthDayDialog.dismiss();
}
});
birthDayDialog.show();
}
xml
`enter code here`<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:baselineAligned="false"
android:orientation="vertical" >
<TextView
android:id="@+id/birthday_dialog_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:gravity="center"
android:minHeight="42dp"
android:text="Year lahir"
android:textSize="14sp" />
<NumberPicker
android:id="@+id/birthdayPicker"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center" >
<Button
android:id="@+id/btn_cancel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Cancel" />
<Button
android:id="@+id/btn_ok"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="OK" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
I have modified @agilanbu 's answer and it can be used as :
private fun createDialogWithoutDateField() {
val alertDialog: AlertDialog?
val builder = AlertDialog.Builder(activity, R.style.AlertDialogStyle)
val inflater = activity!!.layoutInflater
val cal = Calendar.getInstance()
val dialog = inflater.inflate(R.layout.month_year_picker_dialog, null)
val monthPicker = dialog.findViewById(R.id.picker_month) as NumberPicker
val yearPicker = dialog.findViewById(R.id.picker_year) as NumberPicker
monthPicker.minValue = 1
monthPicker.maxValue = 12
monthPicker.value = cal.get(Calendar.MONTH) + 1
val year = cal.get(Calendar.YEAR)
yearPicker.minValue = 1900
yearPicker.maxValue = 3500
yearPicker.value = year
builder.setView(dialog).setPositiveButton(Html.fromHtml("<font color='#FF4081'>Ok</font>")){dialogInterface, which ->
//Toast.makeText(applicationContext,"clicked yes",Toast.LENGTH_LONG).show()
val value = yearPicker.value
dialogInterface.cancel()
}
builder.setNegativeButton(Html.fromHtml("<font color='#FF4081'>Cancel</font>")){dialogInterface, which ->
dialogInterface.cancel()
}
alertDialog = builder.create()
// Set other dialog properties
alertDialog.setCancelable(true)
alertDialog.show()
}
You can get the layout file and styles in @agilanbu 's answer.
I just have the same problem and all solution I found doesn't works with new Android Versions because I can't get the Field of the Reflection of DatePicker
Anyway I solve by doing a Dialog to pick a number, if you need the code:
SingleNumberPickerDialog.java Code
public class SingleNumberPickerDialog extends DialogFragment {
public interface IOnNumberSelected {
void onNumberSelected(int num, int requestCode);
}
private static final String TAG = SingleNumberPickerDialog.class.getSimpleName();
private static final String KEY = TAG + ".key";
// Arguments Keys
private static final String KEY_LABEL = KEY + ".label";
private static final String KEY_START_VALUE = KEY + ".startValue";
private static final String KEY_MIN_VALUE = KEY + ".minValue";
private static final String KEY_MAX_VALUE = KEY + ".maxValue";
private static final String KEY_REQUEST_CODE = KEY + ".requestCode";
// Int Values
private static final int INT_UNDEFINED = -0x1;
@BindView(R2.id.tv_label)
protected TextView mtvLabel;
@BindView(R2.id.np_number)
protected NumberPicker mnpNumber;
private IOnNumberSelected mCallback;
private int mRequestCode;
public static SingleNumberPickerDialog newInstance(String label, int startValue, int minValue, int maxValue, int requestCode){
SingleNumberPickerDialog mInstance = new SingleNumberPickerDialog();
Bundle args = new Bundle();
args.putString(KEY_LABEL, label);
args.putInt(KEY_START_VALUE, startValue);
args.putInt(KEY_MIN_VALUE, minValue);
args.putInt(KEY_MAX_VALUE, maxValue);
args.putInt(KEY_REQUEST_CODE, requestCode);
mInstance.setArguments(args);
return mInstance;
}
/** Override Lifecycle Methods **/
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
try {
mCallback = (IOnNumberSelected) context;
} catch (ClassCastException ccE){
Log.e(TAG, ccE);
}
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View view = inflater.inflate(R.layout.dialog_single_number_picker, container, false);
ButterKnife.bind(this, view);
initOnCreateView();
return view;
}
/** Actions Methods **/
@OnClick(R2.id.b_confirm)
void onClickConfirm(View view){
if(mCallback != null){
mCallback.onNumberSelected(mnpNumber.getValue(), mRequestCode);
}
}
/** Private Methods **/
private void initOnCreateView(){
if(getArguments() != null){
initLabel();
initStartValue();
initMinValue();
initMaxValue();
initRequestCode();
}
}
private void initLabel(){
if(getArguments().containsKey(KEY_LABEL)){
mtvLabel.setText(getArguments().getString(KEY_LABEL));
}
}
private void initStartValue(){
if(getArguments().containsKey(KEY_START_VALUE)){
mnpNumber.setValue(getArguments().getInt(KEY_START_VALUE));
}
}
private void initMinValue(){
if(getArguments().containsKey(KEY_MIN_VALUE)){
mnpNumber.setMinValue(getArguments().getInt(KEY_MIN_VALUE));
}
}
private void initMaxValue(){
if(getArguments().containsKey(KEY_MAX_VALUE)){
mnpNumber.setMaxValue(getArguments().getInt(KEY_MAX_VALUE));
}
}
private void initRequestCode(){
if(getArguments().containsKey(KEY_REQUEST_CODE)){
mRequestCode = getArguments().getInt(KEY_REQUEST_CODE);
}
}
}
dialog_single_number_picker.xml Code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical"
android:background="@color/black"
android:padding="@dimen/padding_3dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@color/white"
android:padding="@dimen/padding_22dp">
<TextView
android:id="@+id/tv_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:textColor="@color/black"
android:textSize="@dimen/text_size_20sp"
android:textStyle="bold"
android:padding="@dimen/padding_25dp"/>
<NumberPicker
android:id="@+id/np_number"
android:layout_width="wrap_content"
android:layout_height="@dimen/height_200dp"
android:layout_gravity="center"/>
<Button
android:id="@+id/b_confirm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/label_confirm"
android:paddingStart="@dimen/padding_15dp"
android:paddingEnd="@dimen/padding_15dp"
style="@style/ButtonAccentWhiteStyle"/>
</LinearLayout>
</LinearLayout>
Usage sample (u need to implement the callback inside ur activity):
int year = DateUtils.getCurrentYear();
SingleNumberPickerDialog mDialog = SingleNumberPickerDialog.newInstance(getString(R.string.label_year), year, year - 50, year + 50, 0x0);
mDialog.setStyle(DialogFragment.STYLE_NO_FRAME, R.style.NoBackgroundDialogStyle);
mDialog.setCancelable(false);
mDialog.show(getSupportFragmentManager(), TAG_DIALOG_YEAR_PICKER);
you can hide day and month from custom datepicker like this:
DatePicker datePicker = (DatePicker) datePickerDialogField.get(obj);
DatePicker monPickerPicker = (DatePicker) datePickerDialogField.get(obj);
Field datePickerFields[] = datePickerDialogField.getType().getDeclaredFields();
for (Field datePickerField : datePickerFields) {
//datePickerField
//mMonthSpinner
if (“mDayPicker”.equals(datePickerField.getName()) || “mDaySpinner”.equals(datePickerField
.getName())) {
datePickerField.setAccessible(true);
Object dayPicker = new Object();
dayPicker = datePickerField.get(datePicker);
((View) dayPicker).setVisibility(View.GONE);
}
if (“mMonthpicker”.equals(datePickerField.getName()) || “mMonthSpinner”.equals(datePickerField
.getName())) {
datePickerField.setAccessible(true);
Object dayPicker = new Object();
dayPicker = datePickerField.get(datePicker);
((View) dayPicker).setVisibility(View.GONE);
}
First, create MonthYearPickerDialog.java class extends with DialogFragment
public class MonthYearPickerDialog extends DialogFragment {
private static final int MAX_YEAR = 2099;
private DatePickerDialog.OnDateSetListener listener;
public void setListener(DatePickerDialog.OnDateSetListener listener) {
this.listener = listener;
}
@SuppressLint("ResourceAsColor")
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.AlertDialogStyle);
LayoutInflater inflater = getActivity().getLayoutInflater();
Calendar cal = Calendar.getInstance();
View dialog = inflater.inflate(R.layout.month_year_picker_dialog, null);
final NumberPicker monthPicker = (NumberPicker) dialog.findViewById(R.id.picker_month);
final NumberPicker yearPicker = (NumberPicker) dialog.findViewById(R.id.picker_year);
monthPicker.setMinValue(1);
monthPicker.setMaxValue(12);
monthPicker.setValue(cal.get(Calendar.MONTH) + 1);
int year = cal.get(Calendar.YEAR);
yearPicker.setMinValue(1900);
yearPicker.setMaxValue(3500);
yearPicker.setValue(year);
builder.setView(dialog).setPositiveButton(Html.fromHtml("<font color='#FF4081'>Ok</font>"), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
listener.onDateSet(null, yearPicker.getValue(), monthPicker.getValue(), 0);
}
}).setNegativeButton(Html.fromHtml("<font color='#FF4081'>Cancel</font>"), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
MonthYearPickerDialog.this.getDialog().cancel();
}
});
return builder.create();
}
}
in styles.xml paste this code.
<style name="AlertDialogStyle" parent="Theme.AppCompat.Light.Dialog">
<item name="android:textColor">#FF4081</item> // you can change the color of the yearPiker dialog
<item name="android:textColorPrimary">#FF4081</item> // you can change the color of the yearPiker dialog
</style>
create month_year_picker_dialog.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="220dp"
android:layout_height="300dp"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="70dp"
android:background="@color/colorAccent"
android:gravity="top">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:elevation="8dp"
android:gravity="center"
android:text="Year"
android:textColor="#ffffff"
android:textSize="22dp"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="horizontal">
<NumberPicker
android:id="@+id/picker_month"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="20dp"
android:descendantFocusability="blocksDescendants"
android:visibility="gone"
tools:ignore="RtlCompat">
</NumberPicker>
<NumberPicker
android:id="@+id/picker_year"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants"
>
</NumberPicker>
</LinearLayout>
</LinearLayout>
</LinearLayout>
In your main class (activity)
private DatePickerDialog createDialogWithoutDateField() {
DatePickerDialog dpd = new DatePickerDialog(this, null, 2014, 1, 24);
try {
java.lang.reflect.Field[] datePickerDialogFields = dpd.getClass().getDeclaredFields();
for (java.lang.reflect.Field datePickerDialogField : datePickerDialogFields) {
if (datePickerDialogField.getName().equals("mDatePicker")) {
datePickerDialogField.setAccessible(true);
DatePicker datePicker = (DatePicker) datePickerDialogField.get(dpd);
java.lang.reflect.Field[] datePickerFields = datePickerDialogField.getType().getDeclaredFields();
for (java.lang.reflect.Field datePickerField : datePickerFields) {
Log.i("test", datePickerField.getName());
if ("mDaySpinner".equals(datePickerField.getName())) {
datePickerField.setAccessible(true);
Object dayPicker = datePickerField.get(datePicker);
((View) dayPicker).setVisibility(View.GONE);
}
}
}
}
}
catch (Exception ex) {
}
return dpd;
}
Finally , call wherever you want
createDialogWithoutDateField().show();